Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to AutoWire spring beans when using Mockito and Junit?

I am trying to set up my class to be used in Junit.

However when I try to do the below I get an error.

Current Test Class:

public class PersonServiceTest {

    @Autowired
    @InjectMocks
    PersonService personService;

    @Before
    public void setUp() throws Exception
    {
        MockitoAnnotations.initMocks(this);
        assertThat(PersonService, notNullValue());

    }

    //tests

Error:

org.mockito.exceptions.base.MockitoException: 
Cannot instantiate @InjectMocks field named 'personService'
You haven't provided the instance at field declaration so I tried to construct the instance.
However the constructor or the initialization block threw an exception : null

How can I fix this?

like image 419
java123999 Avatar asked May 05 '16 14:05

java123999


People also ask

Can you Autowire in a JUnit?

Also note that we can wire other spring beans in our jUnit test classes using @Autowired annotation.

What is difference between @bean and @autowire?

@Bean is just for the metadata definition to create the bean(equivalent to tag). @Autowired is to inject the dependancy into a bean(equivalent to ref XML tag/attribute).

How do you Spring mock beans?

Spring Boot's @MockBean Annotation The mock will replace any existing bean of the same type in the application context. If no bean of the same type is defined, a new one will be added. This annotation is useful in integration tests where a particular bean, like an external service, needs to be mocked.

What is the difference between mock and Autowired?

@InjectMocks is a Mockito mechanism for injecting declared fields in the test class into matching fields in the class under test. It doesn't require the class under test to be a Spring component. @Autowired is Spring's annotation for autowiring a bean into a production, non-test class.


2 Answers

You are not mocking anything in your code. @InjectMocks sets a class where a mock will be injected.

Your code should look like this

public class PersonServiceTest {

    @InjectMocks
    PersonService personService;

    @Mock
    MockedClass myMock;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        Mockito.doReturn("Whatever you want returned").when(myMock).mockMethod;


    }

    @Test()
      public void testPerson() {

         assertThat(personService.method, "what you expect");
      }
like image 111
Kepa M. Avatar answered Oct 29 '22 13:10

Kepa M.


Another solution is to use @ContextConfiguration annotation with static inner configuration class like so:

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
public class PersonServiceTest {
    @Autowired
    PersonService personService;

    @Before
    public void setUp() throws Exception {
        when(personService.mockedMethod()).thenReturn("something to return");
    }

    @Test
    public void testPerson() {
         assertThat(personService.method(), "what you expect");
    }

    @Configuration
    static class ContextConfiguration {
        @Bean
        public PersonService personService() {
            return mock(PersonService.class);
        }
    }
}

Anyway, you need to mock something that the method you want to test uses inside to get desired behaviour of that method. It doesn't make sense to mock the service you're testing.

like image 26
Enigo Avatar answered Oct 29 '22 13:10

Enigo