Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using MockitoJUnitRunner.class instead of SpringJUnit4ClassRunner.class

I have a question about the usage of SpringJUnit4ClassRunner. For pure Junits or Unit Test cases should we use Spring based annotations such as @Autowired along with SpringJUnit4ClassRunner or should we use only the MockitoJUnitRunner instead with the @RunWith annotation at the top of the Test class?

I mean replacing

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "classpath:test-applicationContext.xml" })

with just

@RunWith(MockitoJUnitRunner.class)

at the top of the class. It works for me.

In Junits we normally do not make any external calls such as calls to DB or call to some other web service. We have to mock these external calls using @Mock annotations on this service objects. And then create a real object of the class that we are testing and that depends on these mocks. We can then use @InjectMocks on the real object so that it will be injected with the mocked objects.

Example Service-A->Calls->Service-B->Calls->Service-C

While testing A we should mock Service B & while testing Service-B we should mock Service-C.

Some code Snippet

@RunWith(MockitoJUnitRunner.class)
public class TestServiceA {
    @Mock
    B mockObj;

    @InjectMocks
    A realObj;

    @Test
    public void testServiceA() {
    .....
    .....
    }
}       

So, I feel for Unit test cases we need not rely on Spring container to provide us the instance of the class we are testing.

Please give your suggestions.

Using SpringJUnit4ClassRunner.class instead of MockitoJUnitRunner.class

like image 660
Ayaskant Avatar asked Jun 28 '15 15:06

Ayaskant


People also ask

What can I use instead of MockitoJUnitRunner?

First of all, we remove the reference to MockitoJUnitRunner. Instead, we call the static initMocks() method of the MockitoAnnotations class. We do this in JUnit @Before method of test's class. This initializes any fields with Mockito annotations before each test is executed.

What is the use of @RunWith MockitoJUnitRunner class?

To opt-out from this feature, use @RunWith(MockitoJUnitRunner. Silent. class) Initializes mocks annotated with Mock , so that explicit usage of MockitoAnnotations.

What is the difference between SpringJUnit4ClassRunner and SpringRunner?

There is no difference, from the javadoc: SpringRunner is an alias for the SpringJUnit4ClassRunner.

Why do we need MockitoJUnitRunner?

The main advantage provided by MockitoJunitRunner is relieving you to explicitly invoke MockitoAnnotations. initMocks(Object) when you use the @Mock way to create your mocks. But you could also get a few more misuse reports of the Mockito framework by using this runner that may be missing without using it.


2 Answers

If you try to simply unit test a class without the dependencies, like you describe, there is no need for the SpringJUnit4ClassRunner. This runner is able to generate a complete Spring context with (mock) objects you can define in your (test) application context configuration. With this mechanism the SpringJUnit4ClassRunner is much slower than the regular MockitoJUnitRunner.

The SpringJUnit4ClassRunner is very powerful for integration test purposes.

I default start with the MockitoJUnitRunner and if I reach the limits of this runner, for instance because I need to mock constructors, static methods or private variables, I switch to PowerMockJUnitRunner. This is for me a last resort as it normally tells the code is ‘bad’ and not written to be tested. Other runners are normally not necessary for isolated unit tests.

like image 164
Sven Avatar answered Sep 21 '22 09:09

Sven


Building on Sven's answer, Let us say that you needed to test an assembly of classes while mocking out bits that go to the database, or call an external service, you would look to run the test with SpringJUnit4ClassRunner.
If you were trying to test a Single Java Class as a Unit, mocking out both the integration bits and local collaborators, then running the test with MockitoJUnitRunner is sufficient and faster as well.

like image 27
Karthick Meenakshi Sundaram Avatar answered Sep 22 '22 09:09

Karthick Meenakshi Sundaram