在 @BeforeStep 之前初始化测试中的模拟
Initialize Mocks in test before @BeforeStep
我有一个带有 @BeforeStep 函数的自定义 reader 来初始化一些数据。这些数据来自外部数据库。
@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
}
}
在我的单元测试中,我需要模拟对外部数据库的调用。
@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);
}
}
我面临的问题是,当我启动我的测试时,@BeforeStep 在单元测试的@Before 之前执行。所以 restApiService.getData() returns null 而不是 expectedData.
有没有办法实现我想要的,或者我需要用不同的方法来实现吗?
您确定 BeforeStep
是 Before
注释之前的 运行(通过使用日志记录或类似方式?)。
您的 Mockito 调用可能不完全正确。请尝试使用 Mockito.doReturn(expectedData).when(restApiService).getData()
。
作为替代方法,如果 RestApiService
在您的自定义 reader 中自动装配,您将能够在自定义 reader 上使用 @InjectMocks
注释测试中的声明,这将导致 restApiService
的模拟版本在测试期间被注入 class。
通常在使用基于 Spring 的测试时,尝试将 restApiService
之类的依赖项(您想要模拟的那些)设为 spring beans,然后您可以指示 spring 在 @MockBean
注释的帮助下创建模拟并在应用程序上下文创建期间注入到应用程序上下文中:
import org.springframework.boot.test.mock.mockito.MockBean;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = NedBatchApplication.class)
public class CustomReaderTest {
@MockBean
private RestApiService restApiService;
}
经过与同事的反思后,他给了我一个解决方案:
@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();
(...)
}
}
我有一个带有 @BeforeStep 函数的自定义 reader 来初始化一些数据。这些数据来自外部数据库。
@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
}
}
在我的单元测试中,我需要模拟对外部数据库的调用。
@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);
}
}
我面临的问题是,当我启动我的测试时,@BeforeStep 在单元测试的@Before 之前执行。所以 restApiService.getData() returns null 而不是 expectedData.
有没有办法实现我想要的,或者我需要用不同的方法来实现吗?
您确定 BeforeStep
是 Before
注释之前的 运行(通过使用日志记录或类似方式?)。
您的 Mockito 调用可能不完全正确。请尝试使用 Mockito.doReturn(expectedData).when(restApiService).getData()
。
作为替代方法,如果 RestApiService
在您的自定义 reader 中自动装配,您将能够在自定义 reader 上使用 @InjectMocks
注释测试中的声明,这将导致 restApiService
的模拟版本在测试期间被注入 class。
通常在使用基于 Spring 的测试时,尝试将 restApiService
之类的依赖项(您想要模拟的那些)设为 spring beans,然后您可以指示 spring 在 @MockBean
注释的帮助下创建模拟并在应用程序上下文创建期间注入到应用程序上下文中:
import org.springframework.boot.test.mock.mockito.MockBean;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = NedBatchApplication.class)
public class CustomReaderTest {
@MockBean
private RestApiService restApiService;
}
经过与同事的反思后,他给了我一个解决方案:
@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();
(...)
}
}