【发布时间】:2012-09-03 16:31:58
【问题描述】:
我想避免模拟类的 getClass() 方法,但似乎找不到任何解决方法。我正在尝试测试一个将 HashMap 中的对象类类型存储到稍后使用的特定方法的类。一个简单的例子是:
public class ClassToTest {
/** Map that will be populated with objects during constructor */
private Map<Class<?>, Method> map = new HashMap<Class<?>, Method>();
ClassToTest() {
/* Loop through methods in ClassToTest and if they return a boolean and
take in an InterfaceA parameter then add them to map */
}
public void testMethod(InterfaceA obj) {
final Method method = map.get(obj.getClass());
boolean ok;
if (method != null) {
ok = (Boolean) method.invoke(this, obj);
}
if (ok) {
obj.run();
}
}
public boolean isSafeClassA(final ClassA obj) {
// Work out if safe to run and then return true/false
}
public boolean isSafeClassB(final ClassB obj) {
// Work out if safe to run and then return true/fals
}
}
public interface InterfaceA {
void run()
}
public class ClassA implements InterfaceA {
public void run() {
// implements method here
}
}
public class ClassB implements InterfaceA {
public void run() {
// implements method here
}
}
然后我有一个看起来有点像这样的 JUnit 测试:
@RunWith(PowerMockRunner.class)
@PrepareForTest({ClassA.class})
public class ClassToTestTest {
private final ClassToTest tester = new ClassToTest();
@Test
public void test() {
MockGateway.MOCK_GET_CLASS_METHOD = true;
final ClassA classA = spy(new ClassA());
doReturn(ClassA.class).when(classA).getClass();
MockGateway.MOCK_GET_CLASS_METHOD = false;
tester.testMethod(classA);
verify(classA).run();
}
}
我的问题是虽然在 test() 方法中 classA.getClass();将返回 ClassA,一旦进入测试人员的 testMethod() 方法,它仍会返回 ClassA$EnhancerByMockitoWithCGLIB$... 类,因此我的有用对象将始终为空。
有什么办法可以绕过模拟课程或者我需要做什么来解决这个问题?
提前致谢。
【问题讨论】:
-
看来你不应该首先关心模拟 getClass 。你能发布一些关于测试本身的细节吗?
-
我同意,您要断言什么?
testMethod()正在返回 void,因此assert上没有任何内容,而且看起来您没有更新传入的参数对象。因此我只能假设 testMethod 内部有一些方法调用() 你想verify的互动 -
我希望使用 mockito 来验证测试中的某些操作是否发生。我的地图实际上将类类型存储到一个方法中,以便我可以为实现接口的每个类调用该方法,然后如果相关方法返回 true(或者该类没有方法),我想确保发生了一些行为。
-
你能用伪代码编写你的测试(需求),和/或提供更多的实现代码吗?听起来您正在尝试使用
map来实现某种形式的多态行为,这不是一个好方法。如果传入的对象实现了 InterfaceA,那么您应该对interface进行编码,而不是尝试确定其实际实现类(例如 ClassA),然后尝试执行未在接口上定义的方法。可能我没有理解正确 -
我尝试更新我的代码,使其更准确地适应我要测试的内容。我忽略了任何需要捕获/抛出的异常。
标签: java junit mockito powermock