Ayaskant
Ayaskant

Reputation: 569

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

Upvotes: 21

Views: 17739

Answers (2)

Sven
Sven

Reputation: 2553

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.

Upvotes: 15

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.

Upvotes: 1

Related Questions