Является ли хорошей практикой использование SpringRunner без SpringContext при написании тестовых случаев JUnit?
Я попробовал junit с mockito и написал несколько тестов для программирования.
Вот тестовый пример, который я написал:
@RunWith(SpringRunner.class)
public class TransactionControllerTest {
@Mock
TransactionService transactionServiceMock;
@InjectMocks
TransactionController transactionController;
TransactionRequest txn = new TransactionRequest("123.34", "2018-11-28T23:32:36.312Z");
@Test
public void testSaveTxn() throws Exception {
Mockito.when(transactionServiceMock.saveTxn(Mockito.any(TransactionRequest.class))).thenReturn(true);
ResponseEntity<?> responseEntity = transactionController.saveTxn(null, txn);
assertTrue(responseEntity.getStatusCode().equals(HttpStatus.CREATED));
}
@Test
public void testGetStats() throws Exception {
StatsResponse sr = new StatsResponse("0.00", "0.00", "0.00", "0.00", 0L);
Mockito.when(transactionServiceMock.getStats()).thenReturn(sr);
ResponseEntity<StatsResponse> responseEntity = (ResponseEntity<StatsResponse>) transactionController.getStats(null);
System.out.println("sr response = "+responseEntity.getBody());
assertTrue(responseEntity.getBody().equals(sr));
}
@Test
public void testDelete() throws Exception {
Mockito.doNothing().when(transactionServiceMock).delete();
ResponseEntity<HttpStatus> responseEntity = (ResponseEntity<HttpStatus>) transactionController.deleteTxn(null);
System.out.println("sr response = "+responseEntity.getBody());
assertTrue(responseEntity.getStatusCode().equals(HttpStatus.NO_CONTENT));
}
}
Тестовые случаи работали нормально.
Но моя заявка была отклонена с указанием следующей причины:
Вы использовали SpringRunner, даже если вы не используете SpringContext в тестах, и все высмеиваете.
Теперь, мои проблемы следующие:
Что не так с тестовыми примерами?
В чем смысл вышеуказанной причины отказа?
Как я могу это исправить?
2 ответа
Что не так с тестовыми примерами?
Я думаю, что они хотят, чтобы вы написали весенний тест веб-слоя. Это не тест MVC Spring / Spring-boot. Потому что вы не тестируете контроллер как подпружиненный ресурс. Вы тестируете это как простой Java-класс. Это не докажет, правильно ли он ведет себя как контроллер Spring. Вы не сможете проверить такие функции, как;
- весенний впрыск ресурса
- отправка и проверка запросов
Как я могу это исправить?
Вы должны написать весенний тест MVC и использовать MockMvc
или же RestTemplate
проверить ваш контроллер. Например;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = YourContext.class)
@WebAppConfiguration
public class MyWebTests {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
@Test
public void foo() throws Exception {
mockMvc.perform(get("/status"));
//and verification
}
}
Использование mockito mocks - не самая плохая идея, но вы могли бы использовать auto wired @MockBean
s.
Если это пружинная загрузка, у вас будет больше гибкости. Посмотрите на следующие ресурсы.
https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html https://spring.io/guides/gs/testing-web/
У вас есть жалоба, потому что вам не нужны тестовые функции Spring в вашем тесте. Ваш тест является чистым модульным тестом.
Так что если вы удалите @RunWith(SpringRunner.class)
ничего не изменится для вашего теста. Просто положи туда @ExtendWith(MockitoExtension.class)
SpringRunner
будет инициализировать контекст Spring для вашего теста, чтобы вы могли добавить или смоделировать фрагмент вашего приложения, используя следующие аннотации:
@MockBean
@Autowired
- так далее..