Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SpringBoot Junit bean autowire

I try to write junit test to my service. I use in my project spring-boot 1.5.1. Everything works fine, but when I try to autowire bean (created in AppConfig.class), it gives me NullPointerException. I've tried almost everything.

This is my configuration class:

@Configuration 
public class AppConfig {

@Bean
public DozerBeanMapper mapper(){
    DozerBeanMapper mapper = new DozerBeanMapper();
    mapper.setCustomFieldMapper(new CustomMapper());
    return mapper;
 }
}

and my test class:

@SpringBootTest
public class LottoClientServiceImplTest {
@Mock
SoapServiceBindingStub soapServiceBindingStub;
@Mock
LottoClient lottoClient;
@InjectMocks
LottoClientServiceImpl lottoClientService;
@Autowired
DozerBeanMapper mapper;

@Before
public void setUp() throws Exception {
    initMocks(this);
    when(lottoClient.soapService()).thenReturn(soapServiceBindingStub);
}

@Test
public void getLastResults() throws Exception {

    RespLastWyniki expected = Fake.generateFakeLastWynikiResponse();
    when(lottoClient.soapService().getLastWyniki(anyString())).thenReturn(expected);

    LastResults actual = lottoClientService.getLastResults();

Can someone tells me what's wrong ?

Error log:

java.lang.NullPointerException
at pl.lotto.service.LottoClientServiceImpl.getLastResults(LottoClientServiceImpl.java:26)
at pl.lotto.service.LottoClientServiceImplTest.getLastResults(LottoClientServiceImplTest.java:45)

and this is my service:

@Service
public class LottoClientServiceImpl implements LottoClientServiceInterface {
@Autowired
LottoClient lottoClient;
@Autowired
DozerBeanMapper mapper;
@Override
public LastResults getLastResults() {
    try {
        RespLastWyniki wyniki = lottoClient.soapService().getLastWyniki(new Date().toString());
        LastResults result = mapper.map(wyniki, LastResults.class);
        return result;
    } catch (RemoteException e) {
        throw new GettingDataError();
    }
}
like image 800
franczez Avatar asked Mar 29 '17 16:03

franczez


1 Answers

Ofcourse your dependency will be null,due to the @InjectMocks you are creating a new instance, outside the visibility of Spring and as such nothing will be auto wired.

Spring Boot has extensive testing support and also for replacing beans with mocks, see the testing section of the Spring Boot reference guide.

To fix it work with the framework instead of around it.

  1. Replace @Mock with @MockBean
  2. Replace @InjectMocks with @Autowired
  3. Remove your setup method

Also apparently you only need a mock for the SOAP stub (so not sure what you need to mock for the LottoClient for).

Something like this should do the trick.

@SpringBootTest
public class LottoClientServiceImplTest {

    @MockBean
    SoapServiceBindingStub soapServiceBindingStub;

    @Autowired
    LottoClientServiceImpl lottoClientService;

    @Test
    public void getLastResults() throws Exception {

        RespLastWyniki expected = Fake.generateFakeLastWynikiResponse();
        when(soapServiceBindingStub.getLastWyniki(anyString())).thenReturn(expected);

        LastResults actual = lottoClientService.getLastResults();
like image 77
M. Deinum Avatar answered Sep 20 '22 16:09

M. Deinum