目前,我尝试了解@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";
}
}
要独立测试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"));
}
}
当我第一次执行此测试用例时,我预期结果为“Haus”。乍一看,我看到了这条线
webService = new TranslatorWebService();
将始终使用实例覆盖注入的模拟实例。但是,如何在不改变业务逻辑的情况下避免这种行为?
答案 0 :(得分:7)
好问题。关于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);
}
}