Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mock class in class under test

Tags:

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.

like image 843
NikedLab Avatar asked Jul 19 '13 09:07

NikedLab


People also ask

Should you mock the system under test?

The System Under Test helps us focus on what we're really testing, what Depended-On Components (DOC) interact with it, and how to replace a Depended-On Component with a Test Double (such as a stub, spy, or fake). However, it can be tempting to also stub parts of the System Under Test. This should be avoided.

How do you mock another method in the same class which is being tested?

We can mock runInGround(String location) method inside the PersonTest class as shown below. Instead of using mock(class) here we need to use Mockito. spy() to mock the same class we are testing. Then we can mock the method we want as follows.

How do you mock a class in Java?

The Mockito. mock() method allows us to create a mock object of a class or an interface. We can then use the mock to stub return values for its methods and verify if they were called. We don't need to do anything else to this method before we can use it.

What mock class means?

A mock is a fake class that can be examined after the test is finished for its interactions with the class under test. For example, you can ask it whether a method was called or how many times it was called.


2 Answers

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.

like image 110
cyon Avatar answered Sep 22 '22 15:09

cyon


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()); 
like image 33
mthmulders Avatar answered Sep 18 '22 15:09

mthmulders