简体   繁体   English

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

[英]How to inject mocked dependencies with jmockit

Currently I try to understand how the @Injectable and @Tested annotations are working. 目前,我试图了解@Injectable@Tested注释是如何工作的。 I already did some tests and understood the concept but I didn't get how I can use those annotations in real world applications. 我已经做了一些测试并理解了这个概念,但我没有得到如何在现实世界的应用程序中使用这些注释。

Let's say we are developing a language translator class which depends on a web service. 假设我们正在开发一个依赖于Web服务的语言翻译器类。 The web service methods are encapsulated in a separate class: 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";
    }
}

To test the Translator class independently, we would like to mock the TranslatorWebService class. 要独立测试Translator类,我们想模拟TranslatorWebService类。 According to my understanding, the test class should look like: 根据我的理解,测试类应该如下:

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"));
    }
}

When I executed this test case for the first time, I expected the result "Haus". 当我第一次执行这个测试用例时,我期望结果为“Haus”。 At second glance I saw that the line 乍一看,我看到了那条线

webService = new TranslatorWebService();

will always override the injected mock instance with a real instance. 将始终使用实例覆盖注入的模拟实例。 But how can I avoid this behavior without changing the business logic? 但是,如何在不改变业务逻辑的情况下避免这种行为?

Good question. 好问题。 The thing to notice about JMockit's (or any other mocking API) support for dependency injection is that it's meant to be used only when the code under test actually relies on the injection of its dependencies. 关于依赖注入的JMockit(或任何其他模拟API)支持需要注意的是,只有当被测代码实际依赖于其依赖项的注入时才会使用它。

The example Translator class does not rely on injection for the TranslatorWebService dependency; 这个例子Translator依赖于注射的TranslatorWebService依赖; instead, it obtains it directly through internal instantiation. 相反,它通过内部实例化直接获得它。

So, in a situation like this you can simply mock the dependency: 所以,在这种情况下你可以简单地模拟依赖:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM