最近做了一些Spring Boot单元测试方面的东西,总结一下。
单元测试尽量要和Spring Boot框架减少耦合度,当你在测试某一项功能点是需要mock太多的对象时你就应该意识到这个功能点的耦合度太高了
使用Constructor Injection,不要使用Field Injection。这样才能更容易写单元测试代码。在Spring Framework 4.3以后,如果你只有一个Constructor, 就不再需要写@Autowired,Spring会默认他是autowire目标:
public class OrderEntryServiceImpl implements OrderEntryService { private OrderEntryRepository orderEntryRepository; public OrderEntryServiceImpl(OrderEntryRepository repository) { orderEntryRepository=repository; } }
这样的话在单元测试中初始化对象就很容易
public class OrderEntryServiceTest { @MockBean private OrderEntryRepository orderEntryRepository; private OrderEntryService service; @Before public void setUp() { orderEntryRepository=Mockito.mock(OrderEntryRepository.class); service=new OrderEntryServiceImpl(orderEntryRepository); } private OrderEntry orderEntry=new OrderEntry(); @Test public void findByIdTest() { Mockito.when(orderEntryRepository.findOne(Mockito.anyLong())).thenReturn(orderEntry); OrderEntry entry=service.findById(new Long(1)); assertEquals(entry.getId(),orderEntry.getId()); } @Test public void updateEntryTest() throws Exception { final String orderEntryJson = IOUtils.toString(this.getClass().getResourceAsStream("/static/meta-data/orderentry-example.json"), CharEncoding.UTF_8 ); ObjectMapper mapper= ObjectMapperFactory.getInstance(); Mockito.when(orderEntryRepository.getOne(Mockito.anyLong())).thenReturn(orderEntry); Mockito.doAnswer(returnsFirstArg()).when(orderEntryRepository).save(Mockito.any(OrderEntry.class)); OrderEntry entry =service.update(new Long(1),mapper.readTree(orderJson)); assertEquals(new Long(2),entry.getQuantity()); assertEquals(new Double(10),entry.getUnitPrice()); } }
测试Spring Repository,我们可以使用@DataJpaTest,这样我们就可以使用TestEntityManager来测试我们Repository的功能了。
@RunWith(SpringRunner.class)@DataJpaTestpublic class ClientRepositoryTest { @Autowired private TestEntityManager entityManager; @Autowired private ClientRepository clientRepository; @Test public void testFindByName() { entityManager.persist(new Client("Wang")); Optional<Client> client = clientRepository.findByName("Wang"); assertEquals("Wang", client.get().getName()); } }
测试JSON的序列化和反序列化,需要用@JsonTest
@RunWith(SpringRunner.class) @JsonTestpublic class CustomerJsonTests { private JacksonTester<Customer> json; @Test public void serializeJson() { Customer customer= new Customer( "wang"); assertThat(this.json.write(details)) .extractingJsonPathStringValue("@.name") .isEqualTo("wang"); } }
测试Spring MVC Controller,需要用到@WebMvcTest
@Autowired private MockMvc mockMvc; @MockBean private OrderEntryService orderEntryService; @Test public void updateOrderEntryByIDTest() throws Exception { final String orderEntryJson = IOUtils.toString(this.getClass().getResourceAsStream("/static/meta-data/orderentry-example.json"), CharEncoding.UTF_8 ); Mockito.when(orderEntryService.findById(Mockito.anyLong())).thenReturn(entry); RequestBuilder requestBuilder = MockMvcRequestBuilders.patch("/orderentries/1").accept( MediaType.APPLICATION_JSON) .contentType(contentType) .content(orderEntryJson); MvcResult result= mockMvc.perform(requestBuilder).andReturn(); assertEquals(HttpStatus.ACCEPTED.value(),result.getResponse().getStatus());
时间: 2024-10-10 13:08:23