写JUnit测试用例时不使用SpringContext使用SpringRunner是好习惯吗?
Is it good practice to use SpringRunner without SpringContext when writing JUnit test cases?
我用 mockito 尝试了 junit,并为编码练习编写了一些测试用例。
这是我写的测试用例:
@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));
}
}
测试用例工作正常。
但是我的申请被拒绝了,原因如下:
You were using SpringRunner even though you are not using SpringContext in the tests, and mocking everything.
现在,以下是我的担忧:
测试用例有什么问题?
以上拒绝原因是什么意思?
我该如何纠正?
您有投诉,因为您在测试中不需要 spring 的测试功能。
您的测试是纯单元测试。
因此,如果您删除 @RunWith(SpringRunner.class)
,您的测试不会有任何改变。放在那里 @ExtendWith(MockitoExtension.class)
SpringRunner
将为您初始化 spring 上下文,测试您是否可以使用以下注释注入或模拟应用程序的切片:
@MockBean
@Autowired
- 等..
What's wrong with the test cases?
我想他们想让你做的是写一个 spring web 层测试。这不是 spring MVC test/spring-boot 测试。因为您没有将控制器作为 spring 加载资源进行测试。您将其作为简单的 java class 进行测试。这不会证明它是否正确地作为 Spring 控制器运行。您将无法测试以下功能;
- spring资源注入
- 请求发送和验证
How can i correct that?
您必须编写 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 模拟并不是最糟糕的主意,但您可以使用自动连线 @MockBean
s。
如果这是spring-boot,你会有更大的灵活性。查看以下资源。
https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html
https://spring.io/guides/gs/testing-web/
我用 mockito 尝试了 junit,并为编码练习编写了一些测试用例。
这是我写的测试用例:
@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));
}
}
测试用例工作正常。
但是我的申请被拒绝了,原因如下:
You were using SpringRunner even though you are not using SpringContext in the tests, and mocking everything.
现在,以下是我的担忧:
测试用例有什么问题?
以上拒绝原因是什么意思?
我该如何纠正?
您有投诉,因为您在测试中不需要 spring 的测试功能。 您的测试是纯单元测试。
因此,如果您删除 @RunWith(SpringRunner.class)
,您的测试不会有任何改变。放在那里 @ExtendWith(MockitoExtension.class)
SpringRunner
将为您初始化 spring 上下文,测试您是否可以使用以下注释注入或模拟应用程序的切片:
@MockBean
@Autowired
- 等..
What's wrong with the test cases?
我想他们想让你做的是写一个 spring web 层测试。这不是 spring MVC test/spring-boot 测试。因为您没有将控制器作为 spring 加载资源进行测试。您将其作为简单的 java class 进行测试。这不会证明它是否正确地作为 Spring 控制器运行。您将无法测试以下功能;
- spring资源注入
- 请求发送和验证
How can i correct that?
您必须编写 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 模拟并不是最糟糕的主意,但您可以使用自动连线 @MockBean
s。
如果这是spring-boot,你会有更大的灵活性。查看以下资源。
https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html https://spring.io/guides/gs/testing-web/