Òý×Ó£º×ÔÉÏÊÀ¼ÍÄ©Kent BeckÌá³öTDD(Test-Driven Development)¿ª·¢ÀíÄîÒÔÀ´£¬¿ª·¢ºÍ²âÊԵı߽ç±äµÄÔ½À´Ô½Ä£ºý£¬´ÓÔ±¾ÉÏÏÂÓεÄÒÀÀµ¹ØÏµ£¬Öð²½Ñݱä³ÉÄãÖÐÓÐÎÒ¡¢ÎÒÖÐÓÐÄãµÄ»¥Àµ¹ØÏµ£¬ÉõÖÁºÜ¶à¹«Ë¾ÉèÁ¢ÁËеÄQE(Quality Engineer)ְλ¡£ºÍ´«Í³µÄQA(Quality Assurance)²»Í¬£¬QEµÄÖ÷ÒªÖ°ÔðÊÇͨ¹ý¹¤³Ì»¯µÄÊֶα£Ö¤ÏîÄ¿ÖÊÁ¿£¬ÕâЩÊֶΰüÀ¨µ«²»½öÏÞÓÚ±àдµ¥Ôª²âÊÔ¡¢¼¯³É²âÊÔ£¬´î½¨×Ô¶¯»¯²âÊÔÁ÷³Ì£¬Éè¼ÆÐÔÄܲâÊԵȡ£¿ÉÒÔ˵£¬QEÉíÉϼæ¾ßÁËQAµÄÖÊÁ¿ÒâʶºÍ¿ª·¢µÄ¹¤³ÌÄÜÁ¦¡£´ÓÕâÆª¿ªÊ¼£¬ÎÒ»á´Ó¿ª·¢µÄ½Ç¶È·ÖÈýÆÚÁÄÁÄQEÕâ¸öÒà²âÊÔÒ࿪·¢µÄ½ÇÉ«ËùÐèµÄ»ù±¾¼¼ÄÜ¡£
1 ʲôÊÇMock£¿
ÔÚÈí¼þ²âÊÔÁìÓò£¬MockµÄÒâ˼ÊÇÄ£Ä⣬¼òµ¥À´Ëµ£¬¾ÍÊÇͨ¹ýijÖÖ¼¼ÊõÊÖ¶ÎÄ£Äâ²âÊÔ¶ÔÏóµÄÐÐΪ£¬·µ»ØÔ¤ÏÈÉè¼ÆµÄ½á¹û¡£ÕâÀïµÄ¹Ø¼ü´ÊÊÇÔ¤ÏÈÉè¼Æ£¬Ò²¾ÍÊÇ˵¶ÔÓÚÈÎÒâ±»²âÊԵĶÔÏ󣬿ÉÒÔ¸ù¾Ý¾ßÌå²âÊÔ³¡¾°µÄÐèÒª£¬·µ»ØÌض¨µÄ½á¹û¡£´ò¸ö±È·½£¬¾ÍÏñBBC¼Í¼ƬÀïÃæµÄ¼ÙÆó¶ì£¬¿ÉÒÔ¸ù¾ÝÅÄÉãÐèÒª×÷³ö²»Í¬µÄ·´Ó¦¡£
2 MockÓÐʲôÓã¿
Àí½âÁËʲôÊÇMock£¬ÔÙÀ´¿´MockÓÐÄÄЩÓÃ;¡£Ê×ÏÈ£¬Mock¿ÉÒÔÓÃÀ´½â³ý²âÊÔ¶ÔÏó¶ÔÍⲿ·þÎñµÄÒÀÀµ£¨±ÈÈçÊý¾Ý¿â£¬µÚÈý·½½Ó¿ÚµÈ£©£¬Ê¹µÃ²âÊÔÓÃÀý¿ÉÒÔ¶ÀÁ¢ÔËÐС£²»¹ÜÊÇ´«Í³µÄµ¥ÌåÓ¦Ó㬻¹ÊÇÏÖÔÚÁ÷ÐеÄ΢·þÎñ£¬Õâµã¶¼ÌرðÖØÒª£¬ÒòΪÈκÎÍⲿÒÀÀµµÄ´æÔÚ¶¼»á¼«´óµÄÏÞÖÆ²âÊÔÓÃÀýµÄ¿ÉÇ¨ÒÆÐÔºÍÎȶ¨ÐÔ¡£¿ÉÇ¨ÒÆÐÔÊÇÖ¸£¬Èç¹ûÒªÔÚÒ»¸öеIJâÊÔ»·¾³ÖÐÔËÐÐÏàͬµÄ²âÊÔÓÃÀý£¬ÄÇô³ýÁËÒª±£Ö¤²âÊÔ¶ÔÏó×ÔÉíÄܹ»Õý³£ÔËÐУ¬»¹Òª±£Ö¤ËùÓÐÒÀÀµµÄÍⲿ·þÎñÒ²Äܹ»±»Õý³£µ÷Óá£Îȶ¨ÐÔÊÇÖ¸£¬Èç¹ûÍⲿ·þÎñ²»¿ÉÓã¬ÄÇô²âÊÔÓÃÀýÒ²¿ÉÄÜ»áʧ°Ü¡£Í¨¹ýMockÈ¥³ýÍⲿÒÀÀµÖ®ºó£¬²»¹ÜÊDzâÊÔÓÃÀýµÄ¿ÉÇ¨ÒÆÐÔ»¹ÊÇÎȶ¨ÐÔ£¬¶¼Äܹ»ÉÏÒ»¸ǫ̈½×¡£

MockµÄµÚ¶þ¸öºÃ´¦ÊÇÌæ»»Íⲿ·þÎñµ÷Óã¬ÌáÉý²âÊÔÓÃÀýµÄÔËÐÐËÙ¶È¡£ÈκÎÍⲿ·þÎñµ÷ÓÃÖÁÉÙÊÇ¿ç½ø³Ì¼¶±ðµÄÏûºÄ£¬ÉõÖÁÊÇ¿çϵͳ¡¢¿çÍøÂçµÄÏûºÄ£¬¶øMock¿ÉÒÔ°ÑÏûºÄ½µµÍµ½½ø³ÌÄÚ¡£±ÈÈçÔÀ´Ò»´ÎÃë¼¶µÄÍøÂçÇëÇó£¬Í¨¹ýMock¿ÉÒÔ½µÖÁºÁÃë¼¶£¬ÕûÕû3¸öÊýÁ¿¼¶µÄ²î±ð¡£
MockµÄµÚÈý¸öºÃ´¦ÊÇÌáÉý²âÊÔЧÂÊ¡£ÕâÀï˵µÄ²âÊÔЧÂÊÓÐÁ½²ãº¬Òå¡£µÚÒ»²ãº¬ÒåÊǵ¥Î»Ê±¼äÔËÐеIJâÊÔÓÃÀýÊý£¬ÕâÊÇÔËÐÐËÙ¶ÈÌáÉý´øÀ´µÄÖ±½ÓºÃ´¦¡£¶øµÚ¶þ²ãº¬ÒåÊÇÒ»¸öQEµ¥Î»Ê±¼ä´´½¨µÄ²âÊÔÓÃÀýÊý¡£ÈçºÎÀí½âÕâµÚ¶þ²ãº¬ÒåÄØ£¿ÒÔµ¥ÌåÓ¦ÓÃΪÀý£¬Ëæ×ÅÒµÎñ¸´ÔӶȵÄÉÏÉý£¬ÎªÁËÔËÐÐÒ»¸ö²âÊÔÓÃÀý¿ÉÄÜÐèҪ׼±¸ºÜ¶à²âÊÔÊý¾Ý£¬Óë´Ëͬʱ»¹Òª¾¡Á¿±£Ö¤¶à¸ö²âÊÔÓÃÀýÖ®¼äµÄ²âÊÔÊý¾Ý»¥²»¸ÉÈÅ¡£ÎªÁË×öµ½ÕâÒ»µã£¬QEÍùÍùÐèÒª»¨·Ñ´óÁ¿µÄʱ¼äÀ´Î¬»¤Ò»Ì׿ÉÔËÐеIJâÊÔÊý¾Ý¡£ÓÐÁËMockÖ®ºó£¬ÓÉÓÚÈ¥³ýÁ˲âÊÔÓÃÀýÖ®¼ä¹²ÏíµÄÊý¾Ý¿âÒÀÀµ£¬QE¾Í¿ÉÒÔÕë¶Ôÿһ¸ö»òÕßÿһ×é²âÊÔÓÃÀýÉè¼ÆÒ»Ì×¶ÀÁ¢µÄ²âÊÔÊý¾Ý£¬´Ó¶øºÜÈÝÒ×µÄ×öµ½²»Í¬²âÊÔÓÃÀýÖ®¼äµÄÊý¾Ý¸ôÀëÐÔ¡£¶ø¶ÔÓÚ΢·þÎñ£¬ÓÉÓÚÒ»¸ö΢·þÎñ¿ÉÄܼ¶ÁªÒÀÀµºÜ¶àÆäËûµÄ΢·þÎñ£¬ÔËÐÐÒ»¸ö²âÊÔÓÃÀýÉõÖÁÐèÒª¿çϵͳ׼±¸Ò»ÌײâÊÔÊý¾Ý£¬Èç¹ûûÓÐMock£¬»ù±¾ÉÏ¿ÉÒÔ˵ÊDz»¿ÉÄܵġ£Òò´Ë£¬²»¹ÜÊǵ¥ÌåÓ¦Óû¹ÊÇ΢·þÎñ£¬ÓÐÁËMockÖ®ºó£¬QE¾Í¿ÉÒÔʡȥ´óÁ¿µÄ×¼±¸²âÊÔÊý¾ÝµÄʱ¼ä£¬×¨×¢ÓÚ²âÊÔÓÃÀý±¾Éí£¬×ÔȻҲ¾ÍÌáÉýÁ˵¥È˵IJâÊÔЧÂÊ¡£
3 ÈçºÎMock£¿
˵ÁËÕâô¶àMockµÄºÃ´¦£¬ÄÇô¾¿¾¹ÈçºÎÔÚ²âÊÔÖÐʹÓÃMockÄØ£¿Õë¶Ô²»Í¬µÄ²âÊÔ³¡¾°£¬¿ÉÒÔÑ¡Ôñ²»Í¬µÄMock¿ò¼Ü¡£
3.1 Mockito
Èç¹û²âÊÔ¶ÔÏóÊÇÒ»¸ö·½·¨£¬ÓÈÆäÊÇÉæ¼°Êý¾Ý¿â²Ù×÷µÄ·½·¨£¬ÄÇôMockito¿ÉÄÜÊÇ×îºÃµÄÑ¡Ôñ¡£×÷ΪʹÓÃ×î¹ã·ºµÄMock¿ò¼Ü£¬Mockito³öÓÚEasyMock¶øÊ¤ÓÚEasyMock£¬ÄËÖÁ±»Ä¬Èϼ¯³É½øspring Testing¡£ÆäʵÏÖÔÀíÊÇ£¬Í¨¹ýCGLibÔÚÔËÐÐʱΪÿһ¸ö±»MockµÄÀà»òÕß¶ÔÏó¶¯Ì¬Éú³ÉÒ»¸ö´úÀí¶ÔÏ󣬷µ»ØÔ¤ÏÈÉè¼ÆµÄ½á¹û¡£¼¯³ÉMockitoµÄ»ù±¾²½ÖèÊÇ£º
±ê¼Ç±»MockµÄÀà»òÕß¶ÔÏó£¬Éú³É´úÀí¶ÔÏó
ͨ¹ýMockito API¶¨ÖÆ´úÀí¶ÔÏóµÄÐÐΪ
µ÷ÓôúÀí¶ÔÏóµÄ·½·¨£¬»ñµÃÔ¤ÏÈÉè¼ÆµÄ½á¹û
ÏÂÃæÊÇÎÒGitHubÉϵÄʾÀý¹¤³ÌÀïµÄÒ»¸öÀý×Ó£¬
@RunWith(SpringRunner.class)
@SpringBootTest
public class SignonServiceTests {
// ²âÊÔ¶ÔÏó£¬Ò»¸ö·þÎñÀà
@Autowired
private SignonService signonService;
// ±»MockµÄÀ࣬±»·þÎñÀàËùÒÀÀµµÄÒ»¸öDAOÀà
@MockBean
private SignonDao dao;
@Test
public void testFindAll() {
// SignonService#findAll()ÄÚ²¿»áµ÷ÓÃSignonDao#findAll()
// Èç¹û²»×ö¶¨ÖÆ£¬ËùÓб»MockµÄÀàĬÈÏ·µ»Ø¿Õ
List<Signon> signons = signonService.findAll();
assertTrue(CollectionUtils.isEmpty(signons));
// ¶¨ÖÆ·µ»Ø½á¹û
Signon signon = new Signon();
signon.setUsername("foo");
when(dao.findAll()).thenReturn(Lists.newArrayList(signon));
signons = signonService.findAll();
// ÑéÖ¤·µ»Ø½á¹ûºÍÔ¤ÏÈÉè¼ÆµÄ½á¹ûÒ»ÖÂ
assertEquals(1, signons.size());
assertEquals("foo", signons.get(0).getUsername());
}
} |
´ÓÉÏÃæµÄ²âÊÔÓÃÀý¿ÉÒÔ¿´µ½£¬Í¨¹ýMock·þÎñÀàËùÒÀÀµµÄDAOÀ࣬ÎÒÃÇ¿ÉÒÔÌø¹ýËùÓеÄÊý¾Ý¿â²Ù×÷£¬ÈÎÒâ¶¨ÖÆ·µ»Ø½á¹û£¬´Ó¶ø×¨×¢ÓÚ²âÊÔ·þÎñÀàÄÚ²¿µÄÒµÎñÂß¼¡£ÕâÊÇ´«Í³µÄ·ÇMock²âÊÔËùÄÑÒÔʵÏֵġ£
×¢Ò⣺Mockito²»Ö§³ÖMock˽Óз½·¨»òÕß¾²Ì¬·½·¨£¬Èç¹ûÒªMockÕâÀà·½·¨£¬¿ÉÒÔʹÓÃPowerMock¡£
3.2 WireMock
Èç¹û˵MocketoÊÇÈðÊ¿¾üµ¶£¬¿ÉÒÔMock Everything£¬ÄÇôWireMock¾ÍÊÇΪ΢·þÎñ¶øÉúµÄÒÐÌì½£¡£ºÍ´¦ÔÚ¶ÔÏó²ãµÄMockito²»Í¬£¬WireMockÕë¶ÔµÄÊÇAPI¡£¼ÙÉèÓÐÁ½¸ö΢·þÎñ£¬Service-AºÍService-B£¬Service-AÀïµÄÒ»¸öAPI£¨¹ÃÇÒ³ÆÎªAPI-1£©£¬ÒÀÀµÓÚService-B£¬ÄÇôʹÓô«Í³µÄ²âÊÔ·½·¨£¬²âÊÔAPI-1ʱ±ØÈ»ÐèҪͬʱÆô¶¯Service-B¡£Èç¹ûʹÓÃWireMock£¬ÄÇô¾Í¿ÉÒÔ**ÔÚService-A¶Ë**MockËùÓÐÒÀÀµµÄService-BµÄAPI£¬´Ó¶øÈ¥µôService-BÕâ¸öÍⲿÒÀÀµ¡£
ͬÑù¿´Ò»¸öÎÒGitHubÉϵÄʾÀý¹¤³ÌÀïµÄÒ»¸öÀý×Ó£¬
@RunWith(SpringRunner.class)
@WebMvcTest(VacationController.class)
public class VacationControllerTests {
// Mock±»ÒÀÀµµÄÁíÒ»¸ö΢·þÎñ
@Rule
public WireMockRule wireMockRule = new WireMockRule(3001);
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@Before
public void before() throws JsonProcessingException {
// ¶¨ÖÆ·µ»Ø½á¹û
JsonResult<Boolean> expected = JsonResult.ok(true);
stubFor(get(urlPathEqualTo("/api/vacation/isWeekend"))
.willReturn(aResponse()
.withStatus(OK.value())
.withHeader(CONTENT_TYPE, APPLICATION_JSON_UTF8_VALUE)
.withBody(objectMapper.writeValueAsString(expected))));
}
@Test
public void testIsWeekendProxy() throws Exception {
// ¹¹ÔìÇëÇó²ÎÊý
VacationRequest request = new VacationRequest();
request.setType(PERSONAL);
OffsetDateTime lastSunday = OffsetDateTime.now().with(TemporalAdjusters.previous(SUNDAY));
request.setStart(lastSunday);
request.setEnd(lastSunday.plusDays(1));
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/vacation/isWeekend");
request.toMap().forEach((k, v) -> builder.param(k, v));
JsonResult<Boolean> expected = JsonResult.ok(true);
mockMvc.perform(builder)
// ÑéÖ¤·µ»Ø½á¹ûºÍÔ¤ÏÈÉè¼ÆµÄ½á¹ûÒ»ÖÂ
.andExpect(status().isOk())
.andExpect(content().contentType(APPLICATION_JSON_UTF8))
.andExpect(content().string(objectMapper.writeValueAsString(expected)));
}
} |
ºÍMockitoÀàËÆ£¬ÔÚ²âÊÔÓÃÀýÖм¯³ÉWireMockµÄ»ù±¾²½ÖèÊÇ£º
ÉùÃ÷´úÀí·þÎñ£¬ÒÔÌæ´ú±»MockµÄ΢·þÎñ
ͨ¹ýWireMock API¶¨ÖÆ´úÀí·þÎñµÄ·µ»Ø½á¹û
µ÷ÓôúÀí·þÎñ£¬»ñµÃÔ¤ÏÈÉè¼ÆµÄ½á¹û
ÖµµÃÒ»ÌáµÄÊÇ£¬³ýÁËAPI·½Ê½µÄ¼¯³É£¬WireMock»¹Ö§³ÖÒÔJar°üµÄÐÎʽ¶ÀÁ¢ÔËÐУ¬´ÓÅäÖÃÎļþÖмÓÔØÔ¤ÏÈÉè¼ÆµÄÏìÓ¦½á¹û£¬ÒÔÌæ´ú±»MockµÄ΢·þÎñ¡£¸ü¶àÐÅÏ¢¿ÉÒÔ²ÎÔĹٷ½Îĵµ¡£
ÆäËûÀàËÆµÄMock APIµÄ¿ò¼Ü»¹ÓÐOkHttpµÄmockwebserver£¬mocoºÍmockserver¡£mockwebserverÒ²ÊôÓÚǶÈëʽMock¿ò¼ÜµÄ·¶³ë£¬µ«¹¦ÄܹýÓÚ¼òµ¥¡£moco£¬mockserverËäÈ»¹¦ÄÜÍêÉÆ£¬µ«ÐèÒª¶ÀÁ¢²¿Ê𣬺ÍWireMockÏà±È²»¾ßÓÐÓÅÊÆ¡£
4 С½á
ÒÔÉϾÍÊÇÎÒ¶ÔMock¼¼ÊõµÄһЩ¼û½â£¬»¶ÓÄãµ½ÎÒµÄÁôÑÔ°å·ÖÏí£¬ºÍ´ó¼ÒÒ»Æð¹ý¹ýÕС£×îºó»¹ÒªËµÒ»¾ä£¬Mock¼¼ÊõËäȻǿ´ó£¬µ«Ö÷Òª»¹ÊÇÊÊÓÃÓÚµ¥Ôª²âÊÔ£¬ÔÚ¼¯³É²âÊÔ£¬ÐÔÄܲâÊÔ£¬×Ô¶¯»¯²âÊÔµÈÆäËû²âÊÔÁìÓòʹÓò¢²»¶à¡£ |