±à¼ÍƼö: |
±¾ÎÄÀ´×ÔÓÚinfoq£¬JUnitÊÇ×îÊÜ»¶ÓµÄ»ùÓÚJVMµÄ²âÊÔ¿ò¼Ü£¬ÔÚµÚ5¸öÖ÷Òª°æ±¾ÖнøÐÐÁ˳¹µ×µÄ¸ÄÔì¡£ |
|
¹Ø¼üÒªµã
JUnit 5ÊÇÒ»¸öÄ£¿é»¯ºÍ¿ÉÀ©Õ¹µÄ²âÊÔ¿ò¼Ü£¬Ö§³ÖJava 8¼°¸ü¸ß°æ±¾¡£
JUnit 5ÓÉÈý¸ö²¿·Ö×é³É¡ª¡ªÒ»¸ö»ù´¡Æ½Ì¨¡¢Ò»¸öеıà³ÌºÍÀ©Õ¹Ä£ÐÍJupiter£¬ÒÔ¼°Ò»¸öÃûΪVintageµÄÏòºó¼æÈݵIJâÊÔÒýÇæ¡£
JUnit 5 JupiterµÄÀ©Õ¹Ä£ÐÍ¿ÉÓÃÓÚÏòJUnitÖÐÌí¼Ó×Ô¶¨Ò幦ÄÜ¡£
À©Õ¹Ä£ÐÍAPI²âÊÔÉúÃüÖÜÆÚÌṩÁ˹³×ÓºÍ×¢Èë×Ô¶¨Òå²ÎÊýµÄ·½·¨£¨¼´ÒÀÀµ×¢È룩¡£
JUnit 5ÌṩÁ˷ḻµÄ¹¦ÄÜ¡ª¡ª´Ó¸Ä½øµÄ×¢½â¡¢±êÇ©ºÍ¹ýÂËÆ÷µ½Ìõ¼þÖ´ÐкͶԶÏÑÔÏûÏ¢µÄ¶èÐÔÇóÖµ¡£ÕâÈûùÓÚTDD±àдµ¥Ôª²âÊÔ±äµÃÇá¶øÒ×¾Ù¡£Ð¿ò¼Ü»¹´øÀ´ÁËÒ»¸öÇ¿´óµÄÀ©Õ¹Ä£ÐÍ¡£À©Õ¹¿ª·¢ÈËÔ±¿ÉÒÔʹÓÃÕâ¸öÐÂÄ£ÐÍÏòJUnit
5ÖÐÌí¼Ó×Ô¶¨Ò幦ÄÜ¡£±¾ÎĽ«Ö¸µ¼ÄãÍê³É×Ô¶¨ÒåÀ©Õ¹µÄÉè¼ÆºÍʵÏÖ¡£ÕâÖÖ×Ô¶¨ÒåÀ©Õ¹»úÖÆÎªJava³ÌÐòÔ±ÌṩÁËÒ»ÖÖ´´½¨ºÍÖ´ÐйÊʺÍÐÐΪ£¨¼´BDD¹æ·¶²âÊÔ£©µÄ·½·¨¡£
ÎÒÃÇÊ×ÏÈʹÓÃJUnit 5ºÍÎÒÃǵÄ×Ô¶¨ÒåÀ©Õ¹£¨³ÆÎª¡°StoryExtension¡±£©À´±àдһ¸öʾÀý¹ÊʺÍÐÐΪ£¨²âÊÔ·½·¨£©¡£Õâ¸öʾÀýʹÓÃÁËÁ½¸öеÄ×Ô¶¨Òå×¢½â¡°@Story¡±ºÍ¡°@Scenario¡±£¬ÒÔ¼°¡°Scene¡±À࣬ÓÃÒÔÖ§³ÖÎÒÃǵÄ×Ô¶¨ÒåStoryExtension£º
import org.junit.jupiter.api.extension.ExtendWith;
import ud.junit.bdd.ext.Scenario;
import ud.junit.bdd.ext.Scene;
import ud.junit.bdd.ext.Story;
import ud.junit.bdd.ext.StoryExtension;
@ExtendWith(StoryExtension.class)
@Story(name=¡°Returns go back to the stockpile¡±,
description=¡°...¡°)
public class StoreFrontTest {
@Scenario(¡°Refunded items should be returned to
the stockpile¡±)
public void refundedItemsShouldBeRestocked(Scene
scene) {
scene
.given(¡°customer bought a blue sweater¡±,
() -> buySweater(scene, ¡°blue¡±))
.and(¡°I have three blue sweaters in stock¡±,
() -> assertEquals(3, sweaterCount(scene, ¡°blue¡±),
¡°Store should carry 3 blue sweaters¡±))
.when(¡°the customer returns the blue sweater for
a refund¡±,
() -> refund(scene, 1, ¡°blue¡±))
.then(¡°I should have four blue sweaters in stock¡±,
() -> assertEquals(4, sweaterCount(scene, ¡°blue¡±),
¡°Store should carry 4 blue sweaters¡±))
.run();
}
} |
´Ó´úÂëÆ¬¶ÎÖÐÎÒÃÇ¿ÉÒÔ¿´µ½£¬JupiterµÄÀ©Õ¹Ä£Ðͷdz£Ç¿´ó¡£ÎÒÃÇ»¹¿ÉÒÔ¿´µ½£¬ÎÒÃǵÄ×Ô¶¨ÒåÀ©Õ¹¼°ÆäÏàÓ¦µÄ×¢½âΪ²âÊÔÓÃÀý±àдÕßÌṩÁ˼òµ¥¶ø¸É¾»µÄ·½·¨À´±àдBDD¹æ·¶¡£
×÷Ϊ¶îÍâµÄ½±Àø£¬µ±Ê¹ÓÃÎÒÃǵÄ×Ô¶¨ÒåÀ©Õ¹³ÌÐòÖ´ÐвâÊÔʱ£¬»áÉú³ÉÈçÏÂËùʾµÄÎı¾±¨¸æ£º
STORY: Returns
go back to the stockpile
As a store owner, in order to keep track of stock,
I want to add items back to stock when they¡¯re
returned.
SCENARIO: Refunded items should be returned to
stock
GIVEN that a customer previously bought a blue
sweater from me
AND I have three blue sweaters in stock
WHEN the customer returns the blue sweater for
a refund
THEN I should have four blue sweaters in stock |
ÕâЩ±¨¸æ¿ÉÒÔ×÷ΪӦÓóÌÐò¹¦Äܼ¯µÄÎĵµ¡£
×Ô¶¨ÒåÀ©Õ¹StoryExtensionÄܹ»½èÖúÒÔϺËÐĸÅÄîÀ´Ö§³ÖºÍÖ´ÐйÊʺÍÐÐΪ£º
ÓÃÓÚ×°ÊβâÊÔÀàºÍ²âÊÔ·½·¨µÄ×¢½â
JUnit 5 JupiterµÄÉúÃüÖÜÆÚ»Øµ÷
¶¯Ì¬²ÎÊý½âÎö
×¢½â
ʾÀýÖеġ°@ExtendWith¡±×¢½âÊÇÓÉJupiterÌṩµÄ±ê¼Ç½Ó¿Ú¡£ÕâÊÇÔÚ²âÊÔÀà»ò·½·¨ÉÏ×¢²á×Ô¶¨ÒåÀ©Õ¹µÄ·½·¨£¬Ä¿µÄÊÇÈÃJupiter²âÊÔÒýÇæµ÷Óøø¶¨Àà»ò·½·¨µÄ×Ô¶¨ÒåÀ©Õ¹¡£»òÕߣ¬²âÊÔÓÃÀý±àдÕß¿ÉÒÔͨ¹ý±à³ÌµÄ·½Ê½×¢²á×Ô¶¨ÒåÀ©Õ¹£¬»òÕßͨ¹ý·þÎñ¼ÓÔØÆ÷»úÖÆ½øÐÐ×Ô¶¯×¢²á¡£
ÎÒÃǵÄ×Ô¶¨ÒåÀ©Õ¹ÐèÒªÒ»ÖÖʶ±ð¹ÊÊµķ½·¨¡£Îª´Ë£¬ÎÒÃǶ¨ÒåÁËÒ»¸öÃûΪ¡°Story¡±µÄ×Ô¶¨Òå×¢½âÀ࣬ÈçÏÂËùʾ£º
import org.junit.platform.commons.annotation.Testable;
@Testable
public @interface Story {...} |
²âÊÔÓÃÀý±àдÕßÓ¦¸ÃʹÓÃÕâ¸ö×Ô¶¨Òå×¢½â½«²âÊÔÀà±ê¼ÇΪ¹ÊÊ¡£Çë×¢Ò⣬Õâ¸ö×¢½â±¾ÉíʹÓÃÁËJUnit 5ÄÚÖõġ°@Testable¡±×¢½â¡£Õâ¸ö×¢½âΪIDEºÍÆäËû¹¤¾ßÌṩÁËÒ»ÖÖʶ±ð¿É²âÊÔµÄÀàºÍ·½·¨µÄ·½Ê½¡ª¡ªÒ²¾ÍÊÇ˵£¬´øÓÐÕâ¸ö×¢½âµÄÀà»ò·½·¨¿ÉÒÔͨ¹ýJUnit
5 Jupiter²âÊÔÒýÇæÀ´Ö´ÐС£
ÎÒÃǵÄ×Ô¶¨ÒåÀ©Õ¹»¹ÐèÒªÒ»ÖÖ·½·¨À´Ê¶±ð¹ÊÊÂÖеÄÐÐΪ»ò³¡¾°¡£Îª´Ë£¬ÎÒÃǶ¨ÒåÒ»¸öÃûΪ¡°Scenario¡±µÄ×Ô¶¨Òå×¢½âÀ࣬¿´ÆðÀ´ÏñÕâÑù£º
import org.junit.jupiter.api.Test;
@Test
public @interface Scenario {...} |
²âÊÔÓÃÀý±àдÕßӦʹÓÃÕâ¸ö×Ô¶¨Òå×¢½â½«²âÊÔ·½·¨±ê¼ÇΪ³¡¾°¡£Õâ¸ö×¢½â±¾ÉíʹÓÃÁËJUnit 5 JupiterµÄÄÚÖá°@Test¡±×¢½â¡£µ±IDEºÍ²âÊÔÒýÇæÉ¨Ãè¸ø¶¨µÄÒ»×é²âÊÔÀಢÔÚ¹«¹²ÊµÀý·½·¨ÉÏÕÒµ½@Scenario×¢½âʱ£¬¾Í»á½«ÕâЩ·½·¨±ê¼ÇΪ¿ÉÖ´ÐеIJâÊÔ·½·¨¡£
Çë×¢Ò⣬ÓëJUnit 4µÄ@Test×¢½â²»Í¬£¬JupiterµÄ@Test×¢½â²»Ö§³Ö¿ÉÑ¡µÄ¡°Ô¤ÆÚ¡±Òì³£ºÍ¡°³¬Ê±¡±²ÎÊý¡£JupiterµÄ@Test×¢½âÊÇ´ÓÍ·¿ªÊ¼Éè¼ÆµÄ£¬²¢¿¼Âǵ½ÁË¿ÉÀ©Õ¹ÐÔ¡£
ÉúÃüÖÜÆÚ
JUnit 5 JupiterÌṩÁËÀ©Õ¹»Øµ÷£¬¿ÉÓÃÓÚ·ÃÎʲâÊÔÉúÃüÖÜÆÚʼþ¡£À©Õ¹Ä£ÐÍÌṩÁ˼¸¸ö½Ó¿Ú£¬ÓÃÓÚÔÚ²âÊÔÖ´ÐÐÉúÃüÖÜÆÚµÄ¸÷¸öʱ¼äµã¶Ô²âÊÔ½øÐÐÀ©Õ¹£º

À©Õ¹¿ª·¢Õß¿ÉÒÔ×ÔÓɵØÊµÏÖËùÓлò²¿·ÖÉúÃüÖÜÆÚ½Ó¿Ú¡£
¡°BeforeAllCallback¡±½Ó¿ÚÌṩÁËÒ»ÖÖ·½·¨ÓÃÓÚ³õʼ»¯À©Õ¹²¢ÔÚµ÷ÓÃJUnit²âÊÔÈÝÆ÷ÖеIJâÊÔÓÃÀý֮ǰÌí¼Ó×Ô¶¨ÒåÂß¼¡£ÎÒÃǵÄStoryExtensionÀཫʵÏÖÕâ¸ö½Ó¿Ú£¬ÒÔÈ·±£¸ø¶¨µÄ²âÊÔÀàʹÓÃÁË¡°@Story¡±×¢½â¡£
import org.junit.jupiter.api.extension.BeforeAllCallback;
public class StoryExtension implements BeforeAllCallback
{
@Override
public void beforeAll(ExtensionContext context)
throws Exception {
if (!AnnotationSupport
.isAnnotated(context.getRequiredTestClass(), Story.class))
{
throw new Exception(¡°Use @Story annotation...¡°);
}
}
} |
JupiterÒýÇæ½«Ìṩһ¸öÓÃÓÚÔËÐÐÀ©Õ¹µÄÖ´ÐÐÉÏÏÂÎÄ¡£ÎÒÃÇʹÓÃÕâ¸öÉÏÏÂÎÄÀ´È·¶¨ÕýÔÚÖ´ÐеIJâÊÔÀàÊÇ·ñʹÓÃÁË¡°@Story¡±×¢½â¡£ÎÒÃÇʹÓÃJUnitƽ̨ÌṩµÄAnnotationSupport¸¨ÖúÀàÀ´¼ì²éÊÇ·ñ´æÔÚÕâ¸ö×¢½â¡£
»ØÏëһϣ¬ÎÒÃǵÄ×Ô¶¨ÒåÀ©Õ¹ÔÚÖ´ÐвâÊÔºó»áÉú³ÉBDD±¨¸æ¡£ÕâЩ±¨¸æµÄijЩ²¿·ÖÊÇ´Ó¡°@Store¡±×¢½âµÄÔªËØÖÐÌáÈ¡µÄ¡£ÎÒÃÇʹÓÃbeforeAll»Øµ÷À´±£´æÕâЩ×Ö·û´®¡£ÉÔºó£¬ÔÚÖ´ÐÐÉúÃüÖÜÆÚ½áÊøÊ±£¬ÔÙ»ùÓÚÕâЩ×Ö·û´®Éú³É±¨¸æ¡£ÎÒÃÇʹÓÃÁËÒ»¸ö¼òµ¥µÄPOJO¡£ÎÒÃǽ«Õâ¸öÀàÃüÃûΪ¡°StoryDe??tails¡±¡£ÒÔÏ´úÂëÆ¬¶ÎÑÝʾÁË´´½¨Õâ¸öÀàʵÀýµÄ¹ý³Ì£¬²¢½«×¢½âÔªËØ±£´æµ½ÊµÀýÖУº
public class
StoryExtension implements BeforeAllCallback {
@Override
public void beforeAll(ExtensionContext context)
throws Exception {
Class<?> clazz = context.getRequiredTestClass();
Story story = clazz.getAnnotation(Story.class);
StoryDetails storyDetails = new StoryDetails()
.setName(story.name())
.setDescription(story.description())
.setClassName(clazz.getName());
context.getStore(NAMESPACE).put(clazz.getName(),
storyDetails);
}
} |
ÎÒÃÇÐèÒª½âÊÍһϷ½·¨µÄ×îºóÒ»¸öÓï¾ä¡£ÎÒÃÇʵ¼ÊÉÏÊÇ´ÓÖ´ÐÐÉÏÏÂÎÄÖлñȡһ¸ö´øÓÐÃû×ֵĴ洢£¬²¢½«Ð´´½¨µÄ¡°StoryDe??tails¡±ÊµÀý±£´æµ½Õâ¸ö´æ´¢ÖС£
×Ô¶¨ÒåÀ©Õ¹¿ÉÒÔʹÓô洢À´±£´æºÍ»ñÈ¡ÈÎÒâÊý¾Ý¡ª¡ª»ù±¾ÉϾÍÊÇÒ»¸ö´æÔÚÓÚÄÚ´æÖеÄmap¡£ÎªÁ˱ÜÃâ¶à¸öÀ©Õ¹Ö®¼ä³öÏÖÒâÍâµÄkey³åÍ»£¬JUnitÒýÈëÁËÃüÃû¿Õ¼äµÄ¸ÅÄî¡£ÃüÃû¿Õ¼äÊÇÒ»ÖÖ¶Ô²»Í¬À©Õ¹±£´æµÄÊý¾Ý½øÐиôÀëµÄ·½·¨¡£ÓÃÓÚ¸ôÀëÀ©Õ¹Êý¾ÝµÄÒ»ÖÖ³£Ó÷½·¨ÊÇʹÓÃ×Ô¶¨ÒåÀ©Õ¹ÀàÃû£º
private static
final Namespace NAMESPACE = Namespace
.create(StoryExtension.class); |
ÎÒÃǵÄÀ©Õ¹ÐèÒªÓõ½µÄÁíÒ»¸ö×Ô¶¨Òå×¢½âÊÇ¡°@Scenario¡±×¢½â¡£Õâ¸ö×¢½âÓÃÓÚ½«²âÊÔ·½·¨±ê¼ÇΪ¹ÊÊÂÖеij¡¾°»òÐÐΪ¡£ÎÒÃǵÄÀ©Õ¹½«½âÎöÕâЩ³¡¾°£¬ÒԱ㽫ËüÃÇ×÷ΪJUnit²âÊÔÓÃÀýÀ´Ö´Ðв¢Éú³É±¨¸æ¡£»ØÏëÒ»ÏÂÎÒÃÇ֮ǰ¿´µ½µÄÉúÃüÖÜÆÚͼÖеġ°BeforeEachCallback¡±½Ó¿Ú£¬ÔÚµ÷ÓÃÿ¸ö²âÊÔ·½·¨Ö®Ç°£¬ÎÒÃǽ«Ê¹Óûص÷À´Ìí¼Ó¸½¼ÓÂß¼£º
import org.junit.jupiter.api.extension.BeforeEachCallback;
public class StoryExtension implements BeforeEachCallback
{
@Override
public void beforeEach(ExtensionContext context)
throws Exception {
if (!AnnotationSupport.
isAnnotated(context.getRequiredTestMethod(), Scenario.class))
{
throw new Exception(¡°Use @Scenario annotation...¡°);
}
}
} |
ÈçǰËùÊö£¬JupiterÒýÇæ½«Ìṩһ¸öÓÃÓÚÔËÐÐÀ©Õ¹µÄÖ´ÐÐÉÏÏÂÎÄ¡£ÎÒÃÇʹÓÃÉÏÏÂÎÄÀ´È·¶¨ÕýÔÚÖ´ÐеIJâÊÔ·½·¨ÊÇ·ñʹÓÃÁË¡°@Scenario¡±×¢½â¡£
»Øµ½±¾ÎĵĿªÍ·£¬ÎÒÃÇÌṩÁËÒ»¸ö¹ÊʵÄʾÀý´úÂ룬ÎÒÃǵÄ×Ô¶¨ÒåÀ©Õ¹¸ºÔ𽫡°Scene¡±ÀàµÄʵÀý×¢È뵽ÿ¸ö²âÊÔ·½·¨ÖС£SceneÀàÈòâÊÔÓÃÀý±àдÕßÄܹ»Ê¹Óá°given¡±¡¢¡°then¡±ºÍ¡°when¡±µÈ²½ÖèÀ´¶¨Ò峡¾°£¨ÐÐΪ£©¡£SceneÀàÊÇÎÒÃÇ×Ô¶¨ÒåÀ©Õ¹µÄÖÐÐĵ¥Ôª£¬Ëü°üº¬ÁËÌØ¶¨ÓÚ²âÊÔ·½·¨µÄ״̬ÐÅÏ¢¡£×´Ì¬ÐÅÏ¢¿ÉÒÔÔÚ³¡¾°µÄ¸÷¸ö²½ÖèÖ®¼ä´«µÝ¡£ÎÒÃÇʹÓá°BeforeEachCallback¡±½Ó¿ÚÔÚµ÷ÓòâÊÔ·½·¨Ö®Ç°×¼±¸Ò»¸öSceneʵÀý£ºÈçǰËùÊö£¬JupiterÒýÇæ½«Ìṩһ¸öÓÃÓÚÔËÐÐÀ©Õ¹Ö´ÐÐÉÏÏÂÎÄ¡£ÎÒÃÇʹÓÃÉÏÏÂÎÄÀ´È·¶¨ÕýÔÚÖ´ÐеIJâÊÔ·½·¨ÊÇ·ñʹÓÃÁË¡°@Scenario¡±×¢½â¡£
public class
StoryExtension implements BeforeEachCallback {
@Override
public void beforeEach(ExtensionContext context)
throws Exception {
Scene scene = new Scene()
.setDescription(getValue(context, Scenario.class));
Class<?> clazz = context.getRequiredTestClass();
StoryDetails details = context.getStore(NAMESPACE)
.get(clazz.getName(), StoryDetails.class);
details.put(scene.getMethodName(), scene);
}
} |
ÉÏÃæµÄ´úÂëÓëÎÒÃÇÔÚ¡°BeforeAllCallback¡±½Ó¿Ú·½·¨ÖÐËù×öµÄ·Ç³£ÏàËÆ¡£
¶¯Ì¬²ÎÊý½âÎö
ÏÖÔÚÎÒÃÇ»¹È±ÉÙÒ»¸ö¶«Î÷£¬¼´ÈçºÎ½«³¡¾°ÊµÀý×¢Èëµ½²âÊÔ·½·¨ÖС£JupiterµÄÀ©Õ¹Ä£ÐÍΪÎÒÃÇÌṩÁËÒ»¸ö¡°ParameterResolver¡±½Ó¿Ú¡£Õâ¸ö½Ó¿ÚΪ²âÊÔÒýÇæÌṩÁËÒ»ÖÖ·½·¨£¬ÓÃÓÚʶ±ðÏ£ÍûÔÚ²âÊÔÖ´ÐÐÆÚ¼ä¶¯Ì¬×¢Èë²ÎÊýµÄÀ©Õ¹¡£ÎÒÃÇÐèҪʵÏÖÕâ¸ö½Ó¿ÚµÄÁ½¸ö·½·¨£¬ÒÔ±ã×¢ÈëÎÒÃǵij¡¾°ÊµÀý£º
import org.junit.jupiter.api.extension.ParameterResolver;
public class StoryExtension implements ParameterResolver
{
@Override
public boolean supportsParameter(ParameterContext
parameterContext,
ExtensionContext extensionContext) {
Parameter parameter = parameterContext.getParameter();
return Scene.class.equals(parameter.getType());
}
@Override
public Object resolveParameter(ParameterContext
parameterContext,
ExtensionContext extensionContext) {
Class<?> clazz = extensionContext.getRequiredTestClass();
StoryDetails details = extensionContext.getStore(NAMESPACE)
.get(clazz.getName(), StoryDetails.class);
return details.get(extensionContext
.getRequiredTestMethod().getName());
}
} |
ÉÏÃæµÄµÚÒ»¸ö·½·¨¸æËßJupiterÎÒÃǵÄ×Ô¶¨ÒåÀ©Õ¹ÊÇ·ñ¿ÉÒÔ×¢Èë²âÊÔ·½·¨ËùÐèµÄ²ÎÊý¡£
ÔÚµÚ¶þ¸ö·½·¨¡°resolveParameter()¡±ÖУ¬ÎÒÃÇ´ÓÖ´ÐÐÉÏÏÂÎĵĴ洢ÖлñÈ¡StoryDe??tailsʵÀý£¬È»ºó´ÓStoryDetailsʵÀýÖлñÈ¡ÏÈǰΪ¸ø¶¨²âÊÔ·½·¨´´½¨µÄ³¡¾°ÊµÀý£¬²¢½«Æä´«¸ø²âÊÔÒýÇæ¡£²âÊÔÒýÇæ½«Õâ¸ö³¡¾°ÊµÀý×¢Èëµ½²âÊÔ·½·¨Öв¢Ö´ÐвâÊÔ¡£Çë×¢Ò⣬½öµ±¡°supportsParameter()¡±·½·¨·µ»Øtrueֵʱ²Å»áµ÷Óá°resolveParameter()¡±·½·¨¡£
×îºó£¬ÎªÁËÔÚÖ´ÐÐÍêËùÓйÊʺͳ¡¾°ºóÉú³É±¨¸æ£¬×Ô¶¨ÒåÀ©Õ¹ÊµÏÖÁË¡°AfterAllCallback¡±½Ó¿Ú£º
import org.junit.jupiter.api.extension.AfterAllCallback;
public class StoryExtension implements AfterAllCallback
{
@Override
public void afterAll(ExtensionContext context)
throws Exception {
new StoryWriter(getStoryDetails(context)).write();
}
} |
¡°StoryWriter¡±ÊÇÒ»¸ö×Ô¶¨ÒåÀ࣬¿ÉÉú³É±¨¸æ²¢½«Æä±£´æµ½JSON»òÎı¾ÎļþÖС£
ÏÖÔÚ£¬ÈÃÎÒÃÇ¿´¿´ÈçºÎʹÓÃÕâ¸ö×Ô¶¨ÒåÀ©Õ¹À´±àдBDD·ç¸ñµÄ²âÊÔÓÃÀý¡£Gradle 4.6¼°¸ü¸ß°æ±¾Ö§³ÖʹÓÃJUnit
5ÔËÐе¥Ôª²âÊÔ¡£Äã¿ÉÒÔʹÓÃbuild.gradleÎļþÀ´ÅäÖÃJUnit 5¡£
dependencies
{
testCompile group: ¡°ud.junit.bdd¡±, name: ¡°bdd-junit¡±,
version: ¡°0.0.1-SNAPSHOT¡±
testCompile group: ¡°org.junit.jupiter¡±, name:
¡°junit-jupiter-api¡±,
version: ¡°5.2.0"
testRuntime group: ¡°org.junit.jupiter¡±, name:
¡°junit-jupiter-engine¡±,
version: ¡°5.2.0¡±
}
test {
useJUnitPlatform()
} |
ÈçÄãËù¼û£¬ÎÒÃÇͨ¹ý¡°useJUnitPlatform()¡±·½·¨ÒªÇógradleʹÓÃJUnit 5¡£È»ºóÎÒÃǾͿÉÒÔʹÓÃStoryExtensionÀàÀ´±àд²âÊÔÓÃÀý¡£ÕâÊDZ¾ÎÄ¿ªÍ·¸ø³öµÄʾÀý£º
import org.junit.jupiter.api.extension.ExtendWith;
import ud.junit.bdd.ext.Scenario;
import ud.junit.bdd.ext.Story;
import ud.junit.bdd.ext.StoryExtension;
@ExtendWith(StoryExtension.class)
@Story(name=¡°Returns go back to the stockpile¡±,
description=¡°...¡°)
public class StoreFrontTest {
@Scenario(¡°Refunded items should be returned to
the stockpile¡±)
public void refundedItemsShouldBeRestocked(Scene
scene) {
scene
.given(¡°customer bought a blue sweater¡±,
() -> buySweater(scene, ¡°blue¡±))
.and(¡°I have three blue sweaters in stock¡±,
() -> assertEquals(3, sweaterCount(scene, ¡°blue¡±),
¡°Store should carry 3 blue sweaters¡±))
.when(¡°the customer returns the blue sweater for
a refund¡±,
() -> refund(scene, 1, ¡°blue¡±))
.then(¡°I should have four blue sweaters in stock¡±,
() -> assertEquals(4, sweaterCount(scene, ¡°blue¡±),
¡°Store should carry 4 blue sweaters¡±))
.run();
}
} |
ÎÒÃÇ¿ÉÒÔͨ¹ý¡°gradle testClasses¡±À´ÔËÐвâÊÔ£¬»òÕßʹÓÃÆäËûÖ§³ÖJUnit 5µÄIDE¡£³ýÁ˳£¹æµÄ²âÊÔ±¨¸æÍ⣬×Ô¶¨ÒåÀ©Õ¹»¹ÎªËùÓвâÊÔÀàÉú³ÉBDDÎĵµ¡£
½áÂÛ
ÎÒÃÇÃèÊöÁËJUnit 5À©Õ¹Ä£ÐÍÒÔ¼°ÈçºÎÀûÓÃËüÀ´´´½¨×Ô¶¨ÒåÀ©Õ¹¡£ÎÒÃÇÉè¼Æ²¢ÊµÏÖÁËÒ»¸ö×Ô¶¨ÒåÀ©Õ¹£¬²âÊÔÓÃÀý±àдÕß¿ÉÒÔʹÓÃËüÀ´´´½¨ºÍÖ´ÐйÊÊ¡£¶ÁÕß¿ÉÒÔ´ÓGitHubÉÏ»ñÈ¡´úÂ룬²¢Ñо¿ÈçºÎʹÓÃJupiterÀ©Õ¹Ä£Ðͼ°ÆäAPIÀ´ÊµÏÖ×Ô¶¨ÒåÀ©Õ¹¡£ |