Understanding mocking/stubbing - mockito

407 views Asked by At

I have a very basic understanding in mocking/stubbing.

When you create a stub in test code like:

test h = mock(test);
when(h.hello()).thenReturn(10);

and in source logic I have code like this:

test src = new test();
src.hello();

Now will stub get invoked since I've stubbed the hello method or Since the instance is different will it not get stubbed? Is there any way to stub all instances of the class?

3

There are 3 answers

4
JosefN On BEST ANSWER

A better way to write testable code is not to create cooperating classes by new operator in class code, but to pass cooperating classes as constructor arguments.

class TestedClass{
private final Helper helper;
public TestedClass(Helper helper){
      this.helper = helper;
}

public aMethodUsesHelper(){
    //hello is weird name for method that returns int but it is link to your code
    int aVar =this.helper.hello();
    // ...
}
// ...

Then in test class:

Helper helper = mock(Helper.class);
when(helper.hello()).thenReturn(10);
TestedClass tested = new Tested(helper);
// ...
0
Flying Dumpling On

You need to use the mocked instance to get the stub working. Cheers :)

2
Dave On

You would need to use a factory pattern and inject a mocked factory into the class where the instances are being created.

So, if you want to write tests for some class Foo, which needs to create instances of Bar somewhere in its code, you would need to inject a BarFactory into Foo. Injection can happen the old fashioned way by passing a BarFactory into the constructor or a set method, or with a dependency injection framework like Guice. A brief example of the old-fashioned way:

class Foo {

    private final BarFactory mFactory;

    public Foo(BarFactory factory) {
        mFactory = factory;
    }

    public void someMethodThatNeedsABar() {
        Bar bar = mFactory.create();
    }

}

Now, in your test class you can inject a mocked BarFactory that can produce mocked instances of Bar:

Bar mockBar = mock(Bar.class);
BarFactory mockFactory = mock(BarFactory.class);
when(mockFactory.create()).thenReturn(mockBar);
Foo objectForTest = new Foo(mockFactory);