user3540481
user3540481

Reputation: 221

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?

Upvotes: 3

Views: 7430

Answers (2)

ThomasD
ThomasD

Reputation: 131

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.

Upvotes: 5

henrycharles
henrycharles

Reputation: 1041

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

Upvotes: 1

Related Questions