30

How I can mock with Mockito other classes in my class which is under test?

For example:

MyClass.java

class MyClass {
    public boolean performAnything() {
        AnythingPerformerClass clazz = new AnythingPerformerClass();
        return clazz.doSomething();        
    }
}

AnythingPerformerClass.java

class AnythingPerformerClass {
    public boolean doSomething() {
        //very very complex logic
        return result;
    }
}

And test:

@Test
public void testPerformAnything() throws Exception {
    MyClass clazz = new MyClass();
    Assert.assertTrue(clazz.performAnything());
}

Can I spoof AnythingPerformerClass for excluding unnecessary logic from AnythingPerformerClass? Can I override doSomething() method for simple return true or false?

Why I specify Mockito, because I need it for Android testing with Robolectric.

Lii
  • 11,553
  • 8
  • 64
  • 88
NikedLab
  • 883
  • 4
  • 11
  • 31
  • 1
    Why do you instantiate one instance of the class for each method call? That looks seriously overkill – fge Jul 19 '13 at 10:01

3 Answers3

34

You could refactor MyClass so that it uses dependency injection. Instead of having it create an AnythingPerformerClass instance you could pass in an instance of the class to the constructor of MyClass like so :

class MyClass {

   private final AnythingPerformerClass clazz;

   MyClass(AnythingPerformerClass clazz) {
      this.clazz = clazz;
   }

   public boolean performAnything() {         
     return clazz.doSomething();        
   }
}

You can then pass in the mock implementation in the unit test

@Test
public void testPerformAnything() throws Exception {
   AnythingPerformerClass mockedPerformer = Mockito.mock(AnythingPerformerClass.class);
   MyClass clazz = new MyClass(mockedPerformer);
   ...
}

Alternatively, if your AnythingPerformerClass contains state then you could pass a AnythingPerformerClassBuilder to the constructor.

cyon
  • 9,340
  • 4
  • 22
  • 26
  • According to the [Mockito docs](http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html#2), the default return value for a primitive `boolean` will be `false`, so this test case fails. – mthmulders Jul 19 '13 at 10:09
  • Well, I omitted the step where the method call is mocked out. The OP says "Can I override doSomething() method for simple return true or false?" So I don't think I should constrain the code. – cyon Jul 19 '13 at 10:11
3

As it currently is (both declaration and instantiation of the AnythingPerformerClass inside a method, it's not possible to mock the AnythingPerformerClass using only Mockito.

If possible, move both the declaration and the instantiation of AnythingPerformerClass to the class level: declare an instance variable of type AnythingPerformerClass and have it instantiated by the constructor.

That way, you could more easily inject a mock of AnythingPerformerClass during test, and specify its behaviour. For example:

when(anythingPerformerClassMock.doSomething()).thenReturn(true);

or to test error handling:

when(anythingPerformerClassMock.doSomething()).thenTrow(new NullPointerException());
mthmulders
  • 9,483
  • 4
  • 37
  • 54
0

You can set what to return in Mockito.

when(mock.method()).thenReturn(someValue)
mokuril
  • 742
  • 2
  • 9
  • 14
  • 2
    Will not work, even if you mock both classes in same test, mockito will fail to infer that outer class is expected to use mocked object. – Talha Mar 14 '18 at 07:44