Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
442 views
in Technique[技术] by (71.8m points)

Mocking method call on object created locally using mockito-inline library

For mocking local variable/method call on local object that is constructed inside method under test, we are using PowerMockito library as of now.

We are trying to evaluate whether we can use mockito-inline (version 3.7.7) to do the same. In short, we are trying to intercept construction of object using Mockito.mockConstruction, so that we can specify mocked behavior on object created locally.

Here is a scenario which describes our usage. Since this is legacy code, we are not in a position to change it now.(e.g. Change dependency to instance variable or some other refactoring)

In short, execute() method of class MyClass is constructing object of Util class locally. Since we want to unit test core logic of execute() & hence need to mock process() method called on local Util object created inside execute() method of class MyClass.

public class MyClass {

    public String execute(){

        Util localUtil = new Util();
        String data =  localUtil.process();

        //Core logic of the execute() method that needs to be unit tested...
        //Further update data based on logic define in process() method.
        data = data + " core logic";

        return data;
    }
}

public  class Util {
    public String process(){
        String result = "real";
        //Use various other objects to arrive at result
        return result;
    }
}

@Test
public void testLocalVar(){

        Util util = new Util();
        Assertions.assertEquals("real", util.process()); 

        try (MockedConstruction<Util> mockedConstruction = Mockito.mockConstruction(Util.class);) {

            util = new Util();
            when(util.process()).thenReturn("mocked method data");
            String actualData = util.process();
        
            //This works on local object created here.        
            Assertions.assertEquals("mocked method data",actualData);
            
            //Object,method under test
            MyClass myClass = new MyClass();
            actualData = myClass.execute();
            //This doesn't not works on local object created inside method under test 
            Assertions.assertEquals("mocked method data" + " core logic",actualData); //Fails

        }
    }

Here we are able to define mocked behavior on method on object created locally inside test method. But same thing is not possible with local object created inside actual method under test.

I can see mockedConstruction.constructed() does have every object of class created But not able to specify mocked behavior on on localUtil.process() inside execute() method ..

Any suggestions..

question from:https://stackoverflow.com/questions/65832174/mocking-method-call-on-object-created-locally-using-mockito-inline-library

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In your case, you have to stub the behavior when instructing Mockito to mock the constructor. The Mockito.mockConstruction() is overloaded and allows to not only pass the class you want to mock the constructor for:

@Test
void mockObjectConstruction() {
  try (MockedConstruction<Util> mocked = Mockito.mockConstruction(Util.class,
      (mock, context) -> {
        // further stubbings ...
        when(mock.process()).thenReturn("mocked method data");
   })) {
 
     MyClass myClass = new MyClass();
     actualData = myClass.execute();
  }
}

You can find further possible stubbing scenarios in this article.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...