Vin*_*ega 6 java junit unit-testing easymock powermock
我编写了一个测试方法,其中有一个模拟对象(比如mockA).我可以期待mockA的方法调用实际的程序逻辑.但是,我的程序的一部分也有日志,它需要字符串形式的对象信息.在创建字符串消息时,会在对象上调用一些不必要的方法.因此,在运行测试时,这些方法调用会导致测试失败.这是一个例子.
public class Example {
public int method(Foo foo) {
int a = foo.doSomething(); //required for program.
String logMessage = "foo did something." + foo.getA() + foo.getB().getC();
logger.log(logFile, logMessage);
return a;
}
}
Run Code Online (Sandbox Code Playgroud)
这是示例测试方法.
@Test
public void testMethod() {
int something = 0;
Foo mockFoo = EasyMock.createMock(Foo.class);
expect(mockFoo.doSomething()).andReturn(something);
EasyMock.replay(mockFoo);
assertEquals(new Example().method(mockFoo), something);
EasyMock.verify(mockFoo);
}
Run Code Online (Sandbox Code Playgroud)
这为foo.getA()提供了意外的方法调用.如果我为Foo.class创建了一个漂亮的模拟,它为foo.getB().getC()提供了空指针异常,因为B是foo中的一个对象.我不可能在foo中创建所有对象的漂亮模拟.
反正是否有阻止用于记录的字符串操作?或者,可以做些什么?
谢谢
有两种方法。首先,您模拟正确交互所需的一切Foo
(如其他答案中提到的),或者其次,您提取分离依赖项的任何复杂性。
在您的示例中,复杂性在于消息创建。你可以有:
class FooLogMessageFactory {
public string createLogSomethingMessage(Foo foo) {
return "foo did something." + foo.getA() + foo.getB().getC();
}
}
Run Code Online (Sandbox Code Playgroud)
或者整个日志记录部分位于单独的类中:
class FooDedicatedLogger {
public void logOnSomething(Foo foo) {
String message = "foo did something." + foo.getA() + foo.getB().getC();
logger.log(logFile, message);
}
}
Run Code Online (Sandbox Code Playgroud)
这当然会Example
作为构造函数依赖项注入到您的类中。然后在测试中,您可以轻松地模拟它,并完全忘记日志消息的创建(因为它应该是这样,因为它与实际测试方法的作用无关)。
现在,选择哪种方法很大程度上取决于所涉及对象的复杂性(即实际构建日志消息有多困难?比设置一些额外的模拟调用更困难?)。
归档时间: |
|
查看次数: |
1202 次 |
最近记录: |