我正在编写一个测试类来测试我的'ImporterService'类。此服务读取InputStream并从其数据创建Object。 Object(在本例中为Builder类)在“ImporterService”类中实例化。要测试我的'ImporterService'类,我需要验证Builder类的调用。为此,我想使用Mocking框架,但是如何在'ImporterService'之外创建'Builder'对象的模拟实例?
我的'ImporterService'类的方法如下:
public Builder importFrom(BufferedReader reader) throws IOException {
String someValue = readFrom(reader);
Builder builder = new Builder(); // I need to mock this Builder object...
builder.someMethod(someValue); // to see of a method is called with the expected value
}
我正在考虑将Builder类的创建转移到受保护的方法中,我可以在测试设置时覆盖它。但是这个解决方案对我来说似乎并不是很好,因为'ImporterService'类正在泄漏一些内部逻辑,并且可以通过我不想要的其他类来覆盖该方法。
答案 0 :(得分:2)
如果您使用任何依赖注入库(如Spring),您可以将模拟对象而不是构建器注入ImporterService类。或者你可以用对工厂的调用替换对构造函数的调用,并使用工厂,它会在测试代码中返回模拟。
答案 1 :(得分:1)
是的,你可以按照你的建议做或:
创建一个Factory类,在其中创建Builder
个对象并将其分配给reader类。在您的单元测试中,模拟此工厂并强制它构建您选择的Builder
,您可以在单元测试中检查方法调用。
以下是使用EasyMock显示如何实现此目的的示例:
public class Reader{
private BuilderFactory factory = new BuilderFactory(); // Use production factory by default
public Builder importFrom(BufferedReader reader) throws IOException {
String someValue = readFrom(reader);
Builder builder = factory.buildBuilder();
builder.someMethod(someValue); // to see of a method is called with the expected value
}
}
在您的单元测试中,您执行以下操作:
Reader classUnderTest = new Reader();
BuilderFactory fakeFactory = EasyMock.createNiceMock(BuilderFactory.class);
Builder builder = EasyMock.createMock(Builder.class);
EasyMock.expect(fakeFactory.buildBuilder()).andReturn(builder);
builder.someMethod("value here");
EasyMock.expectLastCall().once();
EasyMock.replay(fakeFactory, builder);
classUnderTest.importFrom(bufferReader);
// Very that all calls were correctly performed on the builder
EasyMock.verify(builder);
答案 2 :(得分:0)
假设您正在使用Mockito(我推荐这个模拟框架),您将能够执行以下操作:
@Test
public void testFoo(@Mocked Builder builder) {
new Expectations() {
{
new Builder();
returns(builder);
builder.setSomemethod()
...
}
};
assertSame(builder,impoertesService.importFrom(...));
}
答案 3 :(得分:0)
某些模拟框架(如PowerMock)可以模拟对象的构造。
答案 4 :(得分:0)
您可以将功能签名更改为以下内容:
public Builder importFrom(BufferedReader reader, Builder builder) throws IOException {
通过这样做,您可以从测试用例中传递任何虚拟实现。这是依赖注入的一种方式。
依赖注入的想法是要求所有依赖项,如果类/函数执行此操作,则代码变得高度可测试。