Phi*_*ler 7 java jmockit mocking
目前,我试图了解@Injectable和@Tested注释是如何工作的.我已经做了一些测试并理解了这个概念,但我没有得到如何在现实世界的应用程序中使用这些注释.
假设我们正在开发一个依赖于Web服务的语言翻译器类.Web服务方法封装在一个单独的类中:
// class to test
public class Translator() {
private TranslatorWebService webService;
public String translateEnglishToGerman(String word){
webService = new TranslatorWebService();
return webService.performTranslation(word);
}
}
// dependency
public class TranslatorWebService {
public String performTranslation(String word){
// perform API calls
return "German Translation";
}
}
Run Code Online (Sandbox Code Playgroud)
为了Translator独立测试该类,我们想模拟TranslatorWebService该类.根据我的理解,测试类应该如下:
public class TranslatorTest {
@Tested private Translator tested;
@Injectable private TranslatorWebService transWebServiceDependency;
@Test public void translateEnglishToGerman() {
new Expectations() {{
transWebServiceDependency.performTranslation("House");
result = "Haus";
}};
System.out.println(tested.translateEnglishToGerman("House"));
}
}
Run Code Online (Sandbox Code Playgroud)
当我第一次执行这个测试用例时,我期待结果"Haus".乍一看,我看到了那条线
webService = new TranslatorWebService();
Run Code Online (Sandbox Code Playgroud)
将始终使用实例覆盖注入的模拟实例.但是,如何在不改变业务逻辑的情况下避免这种行为?
好问题.关于依赖注入的JMockit(或任何其他模拟API)支持需要注意的是,只有当被测代码实际依赖于其依赖项的注入时才会使用它.
该示例Translator类并不能依靠注入的TranslatorWebService依赖; 相反,它通过内部实例化直接获得它.
所以,在这种情况下你可以简单地模拟依赖:
public class TranslatorTest {
@Tested Translator tested;
@Mocked TranslatorWebService transWebServiceDependency;
@Test public void translateEnglishToGerman() {
new Expectations() {{
transWebServiceDependency.performTranslation("House");
result = "Haus";
}};
String translated = tested.translateEnglishToGerman("House");
assertEquals("Haus", translated);
}
}
Run Code Online (Sandbox Code Playgroud)