Home > Net >  Spring autowired dependency is null in class being tested
Spring autowired dependency is null in class being tested

Time:04-13

I'm trying to write a unit test for my PersonController class, which uses a dependency org.modelmapper.ModelMapper. The problem is that when the test calls a method of PersonController that uses the ModelMapper, the ModelMapper is null which results in an error. Clearly it is not being autowired correctly when running the test, but it works when running the application. I am hoping there is a way to fix this problem without needing to add the ModelMapper as a constructor parameter.

The code snippets are shown below:

@SpringBootTest

class PersonControllerTest {

    @Mock
    private IPersonService personService;

    @InjectMocks
    private PersonController underTest;

    @BeforeEach
    void setUp() {
        underTest = new PersonController(personService);
    }

    ...Tests...
}

And the relevant PersonController code is:

public class PersonController {

    @Autowired
    private ModelMapper _modelMapper;

    private final IPersonService _personService;

    public PersonController (IPersonService personService) {
        _personService = personService;
    }

    ...Code that calls _modelMapper...

}

CodePudding user response:

One problem here is that you are creating a controller class manually using new PersonController(personService) so spring annotation @Autowired does not have any effect here (because spring is not creating the class is not configuring it).

Another issue is that you are using mockito @InjectMocks which basically injects mocks (for the unit test) but at the same time, you are using @SpringBootTest which is for integration test (application is started as normal but in test mode).

Based on your description is not clear to me if you are trying to code a unit test or an integration test. so:

  1. If you are coding a unit test, remove @SpringBootTest add ModelMapper as a constructor parameter and instantiate a class with two mocks.
  2. If you are coding an spring integration test, remove @InjectMocks and manual class instantiation of class and flag controller as @Autowire in test.

CodePudding user response:

First of all you should annotate your class PersonControllerTest with

@ExtendWith(SpringExtension.class)
class PersonControllerTest {

or

@ExtendWith(MockitoExtension.class)
class PersonControllerTest {

depending on your use case. This should already fix your problem. If you are still using Junit4 you should use

@RunWith(Springrunner.class)
class PersonControllerTest {

but since you are using

@BeforeEach

that should not be the case :)

EDIT:

When you use ModelMapper via @Autowired you have to use @ExtendWith(SpringExtension.class) . You also have to annotate your class with @SpringBootTest or import the classes that should be available via dependency Injection manually using the @Import annotation.

  • Related