目前我试图了解@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();
将始终使用真实实例覆盖注入的模拟实例。但是,我如何在不更改业务逻辑的情况下避免这种行为呢?
@Mocked
对象也会被注入。根据文档,只有@Injectable
对象支持此功能:为了执行注入,测试类还必须包含一个或多个声明为@Injectable的模拟字段或模拟参数。仅使用@Mocked或@Capturing注释的模拟字段/参数不考虑进行注入。
(官方文档:http://jmockit.github.io/tutorial/BehaviorBasedTesting.html#tested)但无论如何,这个解决方案对我很有效。非常感谢! - Philipp Waller@Mocked
对象不会被注入;它们的类会被模拟。 - RogérioperformTranslation("House")
是否被调用,不需要更多;使用JMockit API,可以将期望的记录块替换为一个期望的验证块:new Verifications() {{ transWebServiceDependency.performTranslation("House"); }};
- Rogério