简体   繁体   中英

Calling a method on Mock object is calling real method instead of mocked implementation

I have my code like below

public process() {
    extract();
    ...
}

private Obj extract() {
    Constructor const = new Constructor();
    Obj object = const.getOBJMethod("12345","c:/file/a.zip",null);
    return object;
}

I am testing the method process using mockito. and in my test class I have written code as

Constructor mocckConst = mock(Constructor.class);
Obj mockObject = mock(Obj.class);
when(mocckConst .getOBJMethod("12345","c:/file/a.zip",null).thenReturn(mockObject);

But while execution of testcase when extract method is called it is going to the real implementation of getOBJMethod().

Constructor class has another inner class. Does that cause any problem? Can anybody tell me what is going wrong here and the solution.

I would like to improvise my process method.

public process(String base) {
    if("abc".equals(base)) {
       ---
    }
    else if("def".equals(base) {
    extract();
    ---
    }
}

This way extract() is called only when basis is def. and I don't want to pass constructor object to process() method then are there any solutions?

In the class that you want to test you create a new Constructor object (via Constructor const = new Constructor() ), hence, you always use the REAL implementation. You have to inject the Constructor object if you want to have it replaced by a mock object for testing. Injection is also possible via constructor for testing.

private final Constructor const; // remove final, if required

public <ConstructorOfYourClassHere>(Constructor const) {
    assert const != null : "const != null"; // use assertions, if you like

    this.const = const;

    // other constructor code...
}

// your other code here...

public process(String base) {
    if("abc".equals(base)) {
        // ---
    }
    else if("def".equals(base) {
        extract();
        // ---
    }
}

private Obj extract() {
    Obj object = const.getOBJMethod("12345","c:/file/a.zip",null);
    return object;
}

Then you can inject the mock when you create the object under test and call process() . Then your mock implementation will be used.

BTW :

  • If you're the owner of the code, you might want to change the visibility of the extract method to protected so that you can test the method, too. See here .
  • Also, you might want to read something about dependency injection in general. Testing with DI is often much easier. You don't have to use a DI-framework, just inject your dependencies via method parameters or via constructor at object creation time.

You can spy the Constructor object if you want to have it testable with a mock.

public class Test{

    @spy
    Constructor const;

    public process() {
        extract();
        ...
    }

    private Obj extract() {

        Obj object = const.getOBJMethod("12345","c:/file/a.zip",null);
        return object;
    }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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