DarkMatter in Cyberspace
  • Home
  • Categories
  • Tags
  • Archives

怎样在类外部测试私有方法和设置/读取私有变量


有些私有方法有很明确的功能,算法比较复杂,不测可能会出问题。测的话最简单的方法是把测试用例写在类内部,例如下面的类:

package com.boco.godu.gapi;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

public class ConnManager {

private static String buildConnPoolID(int connType, String ip, int port, String loginArg1, String loginArg2) {

return connType + ip;

}

@Test

public void testPoolID() {

assertEquals("23ipstr", buildConnPoolID(23, "ipstr", 3, null, null));

}

}

但这样测会有几个问题:首先是如果测试方法很多,会把源代码文件搞得很臃肿,其次发布的时候需要将测试代码删除(毕竟不是产品的一部分),以后再需要测试的时候还得重写,最后这样的测试在BVT的时候无法运行,工作量也无法体现出来(BVT的测试用例都是写在单独的测试类中)。所以理想的方法是把测试方法写在单独的测试类中。

下面采用Java的反射机制实现这一目标。首先是被测类:

package org.leechau.testPrivateMethod;

public class ClassTested {

private String buffer ;

private String privateFoo (int a, String b) {

return a + b;

}

}

然后是测试类:

package org.leechau.testPrivateMethod;

import static org.junit.Assert.assertEquals;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

import org.junit.BeforeClass;

import org.junit.Test;

public class PrivateMethodTest {

private static ClassTested oClassTested;

private static Method newPrivateFoo;

private static Field buffer;

@BeforeClass

public static void buildDupObj() throws NoSuchMethodException {

// Get the class of the private method.

oClassTested = new ClassTested();

Class<?> cNewClassTested = oClassTested. getClass ();

// Change the property of the private method to be accessible.

newPrivateFoo = cNewClassTested. getDeclaredMethod ("privateFoo",

int.class, String.class);

newPrivateFoo. setAccessible (true);

buffer = cNewClassTested . getDeclaredField ("buffer");

buffer. setAccessible (true);

buffer. set ( oClassTested , "abcdefg");

}

@Test

public void privateFooTest() throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {

// Run the private method.

Object oActual = newPrivateFoo. invoke (oClassTested, new Integer(169), new String("_ABC"));

// Test the private method

String sActual = oActual.toString();

String sExpected = "169_ABC";

assertEquals(sActual, sExpected);

Object result = buffer. get ( oClassTested );

assertEquals("bcdefg", result);

}

@Test

public void privateFooTest2() throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {

Object oActual = newPrivateFoo. invoke (oClassTested, new Integer(169), new String("_DEF"));

String sActual = oActual.toString();

String sExpected = "169_DEF";

assertEquals(sActual, sExpected);

}

}

这里要注意的是,JUnit 4里一个测试类执行顺序为:@BeforeClass –> @Before –> @Test –> @After –> @AfterClass,其中@BeforeClass和@AfterClass标记仅在测试类的初始化和清理时运行一次且必须是static方法,而@Before/@After标记是在每个@Test方法运行前/后都运行一遍,因此每一个测试方法的调用顺序为:@Before –> @Test –> @After。在JUnit 3里没有@BeforeClass和@AfterClass标记,起初始化和清理任务的方法必须命名为SetUp()和TearDown()。



Published

Feb 23, 2011

Last Updated

Feb 23, 2011

Category

Tech

Tags

  • JUnit 10
  • private method 1
  • test 4

Contact

  • Powered by Pelican. Theme: Elegant by Talha Mansoor