3

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?

user3540481
  • 221
  • 3
  • 13

2 Answers2

5

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.
Community
  • 1
  • 1
ThomasD
  • 131
  • 1
  • 6
  • Are there any other way? I don't want to pass Constructor object to process method(). Because this method is generic method which behaves in 2 ways based on it's input. Constructor object is required in only one case. – user3540481 Aug 04 '14 at 07:23
  • @user3540481: updated answer according to your updated question. Next time, please be as specific with your code example as possible. Changing the question will result in the answers becoming obsolete. – ThomasD Aug 04 '14 at 07:45
1

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;
    }
    }
henrycharles
  • 1,019
  • 6
  • 28
  • 66