如何使用jmockit注入模拟的依赖项

时间:2014-11-05 13:46:18

标签: java mocking jmockit

目前,我尝试了解@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();

将始终使用实例覆盖注入的模拟实例。但是,如何在不改变业务逻辑的情况下避免这种行为?

1 个答案:

答案 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);
    }
}