简体   繁体   中英

Initialize Mocks in test before @BeforeStep

I have a custom reader with an @BeforeStep function in order to initialize some data. These data are comming from an external database.

@Component
public class CustomReader implements ItemReader<SomeDTO> {

    private RestApiService restApiService;

    private SomeDTO someDTO;

    @BeforeStep
    private void initialize() {
        someDTO = restApiService.getData();
    }

    @Override
    public SomeDTO read() {
        ...    
        return someDTO
    }

}

In my unit test i need to mock the calls to the external database.

@RunWith(SpringRunner.class)
@SpringBootTest(classes = NedBatchApplication.class)
public class CustomReaderTest {

    @Autowired
    CustomReader customReader;

    @Mock
    RestApiService restApiService;

    @Before
    private void setup() {
        MockitoAnnotations.initMocks(this);
        ReflectionTestUtils.setField(customReader, "restApiService", restApiService);
        Mockito.when(restApiService.getData().thenReturn(expectedData);
    }
}

The problem i am facing is the @BeforeStep is executed before the @Before from the unit test, when i lauch my Test. So restApiService.getData() returns null instead of expectedData.

Is there a way to achieve what i want or do i need to do it with a different approach ?

Are you certain that the BeforeStep is running before the Before annotation (by using logging or similar?).

It's possible your Mockito invocation is not fully correct. Try using Mockito.doReturn(expectedData).when(restApiService).getData() instead.

As an alternative approach, if the RestApiService was autowired in your custom reader, you'd be able to use the @InjectMocks annotation on the custom reader declaration in your test, which would cause the mocked version of your restApiService to be injected to the class during the test.

Usually when using Spring based tests, try to make dependencies like restApiService (the ones you would like to mock) to be spring beans, and then you can instruct spring to create mock and inject into application context during the application context creation with the help of @MockBean annotation:

import org.springframework.boot.test.mock.mockito.MockBean;  
@RunWith(SpringRunner.class)
@SpringBootTest(classes = NedBatchApplication.class)
public class CustomReaderTest {

    @MockBean
    private RestApiService restApiService; 
}

After some reflexion with a co-worker he gave me a solution :

@RunWith(SpringRunner.class)
@SpringBootTest(classes = NedBatchApplication.class)
public class CustomReaderTest {

  CustomReader customReader;

  @Mock
  RestApiService restApiService;

  @Before
  private void setup() {
      MockitoAnnotations.initMocks(this);
      Mockito.when(restApiService.getData().thenReturn(expectedData);

      this.customReader = new CustomReader(restApiService);
  }

 @Test
 public void test() {
   customReader.initialize();
   (...)
 }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM