Mockito : how to verify method was called on an object created within a method? Mockito : how to verify method was called on an object created within a method? java java

Mockito : how to verify method was called on an object created within a method?


Dependency Injection

If you inject the Bar instance, or a factory that is used for creating the Bar instance (or one of the other 483 ways of doing this), you'd have the access necessary to do perform the test.

Factory Example:

Given a Foo class written like this:

public class Foo {  private BarFactory barFactory;  public Foo(BarFactory factory) {    this.barFactory = factory;  }  public void foo() {    Bar bar = this.barFactory.createBar();    bar.someMethod();  }}

in your test method you can inject a BarFactory like this:

@Testpublic void testDoFoo() {  Bar bar = mock(Bar.class);  BarFactory myFactory = new BarFactory() {    public Bar createBar() { return bar;}  };  Foo foo = new Foo(myFactory);  foo.foo();  verify(bar, times(1)).someMethod();}

Bonus: This is an example of how TDD can drive the design of your code.


The classic response is, "You don't." You test the public API of Foo, not its internals.

Is there any behavior of the Foo object (or, less good, some other object in the environment) that is affected by foo()? If so, test that. And if not, what does the method do?


If you don't want to use DI or Factories. You can refactor your class in a little tricky way:

public class Foo {    private Bar bar;    public void foo(Bar bar){        this.bar = (bar != null) ? bar : new Bar();        bar.someMethod();        this.bar = null;  // for simulating local scope    }}

And your test class:

@RunWith(MockitoJUnitRunner.class)public class FooTest {    @Mock Bar barMock;    Foo foo;    @Test    public void testFoo() {       foo = new Foo();       foo.foo(barMock);       verify(barMock, times(1)).someMethod();    }}

Then the class that is calling your foo method will do it like this:

public class thirdClass {   public void someOtherMethod() {      Foo myFoo = new Foo();      myFoo.foo(null);   }}

As you can see when calling the method this way, you don't need to import the Bar class in any other class that is calling your foo method which is maybe something you want.

Of course the downside is that you are allowing the caller to set the Bar Object.

Hope it helps.