How to AutoWire spring beans when using Mockito and Junit?

20,040

Solution 1

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");
      }

Solution 2

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.

Solution 3

You're misunderstanding the purpose of the mock here.

When you mock out a class like this, you are pretending as if it's been injected into your application. That means you don't want to inject it!

The solution to this: set up whatever bean you were intending to inject as @Mock, and inject them into your test class via @InjectMocks.

It's unclear where the bean you want to inject is since all you have is the service defined, but...

@RunWith(MockitoJUnitRunner.class);
public class PersonServiceTest {

    @Mock
    private ExternalService externalSvc;

    @InjectMocks
    PersonService testObj;
}
Share:
20,040
java123999
Author by

java123999

Updated on July 09, 2022

Comments

  • java123999
    java123999 almost 2 years

    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?

  • java123999
    java123999 about 8 years
    Im not understanding, what does the .doReturn metho do?
  • Kepa M.
    Kepa M. about 8 years
    I think here you will find a good explanation of how the mocking process goes. If you have further questions after reading it I will try to help you. dzone.com/articles/use-mockito-mock-autowired