简体   繁体   English

在JUnit的方法中模拟变量

[英]Mocking variable in method in junit

How can I mock clientInstance.execute if I am writing Junit for the following method? 如果我为以下方法编写Junit,如何模拟clientInstance.execute

public class ClassName{
    public static <type> fun(){
        HttpClient clientInstance = null;
        // clientInstance initialised here 

        response = clientInstance.execute();
        //I am trying to mock clientInstance.execute 
    }
}

As kryger pointed out, you'd better redesign your code for testability: 正如kryger指出的那样,您最好重新设计代码以提高可测试性:

public class ClassName {
    public static <type> fun(HttpClient clientInstance){
        response = clientInstance.execute();
        //I am trying to mock response.execute 
    }
}

This is called dependency injection . 这称为依赖注入 Which is a fancy term for putting the burden on the caller of this code. 这是给代码调用者带来负担的一个花哨的术语。 JBRainsberger wrote an excellent post about it. JBRainsberger撰写了一篇很棒的文章

If you can't modify the signature of fun() because too many other code depends on it, then you can overload it: 如果由于太多其他代码依赖fun()而不能修改fun()的签名,则可以重载它:

public class ClassName {
    /* this method is *not* going to be tested */
    public static <type> fun(HttpClient clientInstance){
        HttpClient clientInstance = null;
        // clientInstance initialised here 
        return fun(clientInstance);
    }

    /* this method is going to be tested */
    public static <type> fun(HttpClient clientInstance){
        response = clientInstance.execute();
        // mocking clientInstance.execute() will be easy now
    }
}

What if the HttpClient initialisation is tricky and you want to test it? 如果HttpClient初始化很棘手并且您想测试它怎么办? You can refactor it into another method: 您可以将其重构为另一种方法:

public class ClassName {
    /**
      * Package-private for testing reasons.
      * Do not call it from within the class in production code!
    */
    static HttpClient createHttpClient() {
        HttpClient clientInstance = null;
        // clientInstance initialised here 
        return clientInstance;
    }

    /* this method is *not* going to be tested */
    public static <type> fun(HttpClient clientInstance){
        HttpClient clientInstance = createHttpClient();
        return fun(clientInstance);
    }

    /* this method is going to be tested */
    public static <type> fun(HttpClient clientInstance){
        response = clientInstance.execute();
        // mocking clientInstance.execute() will be easy now
    }
}

If everything else fails, you can use PowerMock to mock constructors. 如果其他所有操作失败,则可以使用PowerMock模拟构造函数。 I've never seen a case where it was worth the trouble. 我从未见过值得为此烦恼的情况。 Anyway, this Q&A explains how to use it. 无论如何, 此问答解释了如何使用它。

You can create a mock instance for clientInstance using Mockito.mock and then define what it returns using Mockito.when , like so: 您可以使用Mockito.mock为clientInstance创建一个模拟实例,然后使用Mockito.mock定义它返回的Mockito.when ,如下所示:

HttpClient clientInstance = Mockito.mock(HttpClient.class); // initialize mock
Object mockReturn = new Object(); // define your return object
Mockito.when(clientInstance.execute()).thenReturn(mockReturn); // define what mock returns
Object response = clientInstance.execute(); // call your mock

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

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