Note
ãã®ããŒãžã«ã¢ã¯ã»ã¹ããã«ã¯ãæ¿èªãå¿ èŠã§ãã ãµã€ã³ã€ã³ãŸãã¯ãã£ã¬ã¯ããªã®å€æŽã詊ãããšãã§ããŸãã
ãã®ããŒãžã«ã¢ã¯ã»ã¹ããã«ã¯ãæ¿èªãå¿ èŠã§ãã ãã£ã¬ã¯ããªã®å€æŽã詊ãããšãã§ããŸãã
åäœãã¹ããèšè¿°ããå©ç¹ã¯å€æ°ãããŸãã ååž°ã«åœ¹ç«ã¡ãããã¥ã¡ã³ããæäŸããåªããèšèšã容æã«ããŸãã ããããåäœãã¹ããèªã¿ã«ãããå£ãã«ããå Žåã¯ãã³ãŒã ããŒã¹ã«å€§æ··ä¹±ãåŒãèµ·ããå¯èœæ§ããããŸãã ãã®èšäºã§ã¯ã.NET Core ããã³ .NET Standard ãããžã§ã¯ãããµããŒãããããã®åäœãã¹ããèšèšããããã®ãã¹ã ãã©ã¯ãã£ã¹ã«ã€ããŠèª¬æããŸãã ãã¹ãã®å埩æ§ãç¶æããçè§£ããããæ¹æ³ãåŠç¿ããŸãã
ã³ãŒãäŸã§ã¯ xUnit.net ãã¹ã ãã¬ãŒã ã¯ãŒã¯ã䜿çšããŸãããã®ãã¬ãŒã ã¯ãŒã¯ã§ã¯ã[Fact] 屿§ãš [Theory] 屿§ãããã³ Assert ã¯ã©ã¹ãæäŸãããŸãã xUnit.net ã®æŠèŠã«ã€ããŠã¯ãdotnet test ãš xUnit ã䜿çšãã .NET ã§ã® C# ã®åäœãã¹ãã«é¢ããããŒãžãåç
§ããŠãã ããã ãã¹ã ãã©ã¯ãã£ã¹ã¯ãä»ã®.NETãã¹ã ãã¬ãŒã ã¯ãŒã¯ã«ãé©çšãããŸãã
ãžã§ã³ã»ãªãŒã¹ãããã€ã»ãªã·ã§ããŽã«ç¹å¥ãªæè¬ã蟌ããŠ
ãŠããã ãã¹ãã®ã¡ãªãã
次ã®ã»ã¯ã·ã§ã³ã§ã¯ã.NET Core ããã³ .NET Standard ãããžã§ã¯ãã®åäœãã¹ããèšè¿°ããããã€ãã®çç±ã«ã€ããŠèª¬æããŸãã
æ©èœãã¹ãã®å®è¡æéã®ççž®
æ©èœãã¹ãã¯ã³ã¹ããããããŸãã éåžžãã¢ããªã±ãŒã·ã§ã³ãéããæåŸ ãããåäœãæ€èšŒããããã«ãŠãŒã¶ãŒ (ãŸãã¯ä»ã®ãŠãŒã¶ãŒ) ãåŸãå¿ èŠãããäžé£ã®æé ãå®è¡ããå¿ èŠããããŸãã ãããã®æé ã¯ãåžžã«ãã¹ã¿ãŒã«èªèããããšã¯éããŸããã 圌ãã¯ãã¹ããå®è¡ããããã«ããã®å°åã§ããç¥èã®ããäººã«æãå·®ã䌞ã¹ãå¿ èŠããããŸãã ãã¹ãèªäœã¯ãç°¡åãªå€æŽã«ã¯æ°ç§ãããããšãã§ãã倧ããªå€æŽã®å Žåã¯æ°åãããå ŽåããããŸãã æåŸã«ãã·ã¹ãã ã§è¡ããã¹ãŠã®å€æŽã«å¯ŸããŠããã®ããã»ã¹ãç¹°ãè¿ãå¿ èŠããããŸãã äžæ¹ãåäœãã¹ãã¯ããªç§ããã£ãŠããããã¿ã³ãæŒããšå®è¡ã§ããã·ã¹ãã ã«é¢ããç¥èã¯å¿ ãããå¿ èŠãããŸããã ãã¹ãã©ã³ããŒããã¹ãã®ååŠã倿ããå人ã倿ããããã§ã¯ãããŸããã
ååž°ã®é²æ¢
ååž°ã®æ¬ é¥ã¯ãã¢ããªã±ãŒã·ã§ã³ã«å€æŽãå ãããããšãã«çºçãããšã©ãŒã§ãã ãã¹ãæ åœè ã¯ãæ°ããæ©èœããã¹ãããã ãã§ãªããäºåã«ååšããŠããæ©èœããã¹ãããŠãæ¢åã®æ©èœãåŒãç¶ãæåŸ ã©ããã«æ©èœããããšã確èªããã®ãäžè¬çã§ãã åäœãã¹ãã§ã¯ããã«ãã®ãã³ã«ããŸãã¯ã³ãŒãè¡ã倿ŽããåŸã§ããäžé£ã®ãã¹ãå šäœãåå®è¡ã§ããŸãã ãã®æ¹æ³ã¯ãæ°ããã³ãŒããæ¢åã®æ©èœãå£ããªããšãã確信ãé«ããã®ã«åœ¹ç«ã¡ãŸãã
å®è¡å¯èœãªããã¥ã¡ã³ã
ç¹å®ã®ã¡ãœãããäœãè¡ããããŸãã¯ç¹å®ã®å ¥åã«ãã£ãŠã©ã®ããã«åäœãããã¯ãå¿ ãããæããã§ãããšã¯éããŸããã 空çœã® æååãŸã㯠null ãæž¡ããšããã®ã¡ãœããã¯ã©ã®ããã«åäœããŸããã äžé£ã®é©åãªååã®åäœãã¹ããããå Žåãåãã¹ãã§ã¯ãç¹å®ã®å ¥åã«å¯ŸããŠäºæ³ãããåºåãæç¢ºã«èª¬æããå¿ èŠããããŸãã ããã«ããã¹ãã¯å®éã«åäœããããšã確èªã§ããå¿ èŠããããŸãã
çµåãå°ãªãã³ãŒã
ã³ãŒããå¯çµåãããŠãããšãåäœãã¹ããå°é£ã«ãªãå ŽåããããŸãã äœæããŠããã³ãŒãã®åäœãã¹ããäœæããªããšãçµåãããŸãæããã§ãªãå ŽåããããŸãã ãããã£ãŠãã³ãŒãã«å¯Ÿãããã¹ããèšè¿°ããéã«ã¯ãå¿ ç¶çã«ã³ãŒããåé¢ããŸããããããªããšããã¹ããå°é£ã«ãªãããã§ãã
åªããåäœãã¹ãã®ç¹æ§
é©åãªåäœãã¹ããå®çŸ©ããéèŠãªç¹æ§ãããã€ããããŸãã
- é«é: æçãããããžã§ã¯ãã§äœåãã®åäœãã¹ãã宿œããããšã¯çãããããŸããã åäœãã¹ãã®å®è¡ã«ã¯å°ãæéãããããŸãã ããªç§ã
- åé¢: åäœãã¹ãã¯ã¹ã¿ã³ãã¢ãã³ã§ãããåé¢ããŠå®è¡ã§ãããã¡ã€ã« ã·ã¹ãã ãããŒã¿ããŒã¹ãªã©ã®å€éšèŠå ãžã®äŸåé¢ä¿ã¯ãããŸããã
- å埩å¯èœ: åäœãã¹ãã®å®è¡ã¯ããã®çµæãšäžèŽããŠããå¿ èŠããããŸãã å®è¡ã®éã«äœã倿Žããªãå Žåããã¹ãã¯åžžã«åãçµæãè¿ããŸãã
- èªå·±ãã§ãã¯: ãã¹ãã¯ã人éã®æäœãªãã§æåãŸãã¯å€±æãããã©ãããèªåçã«æ€åºããå¿ èŠããããŸãã
- ã¿ã€ã ãªãŒ: åäœãã¹ãã§ã¯ããã¹ã察象ã®ã³ãŒããšæ¯èŒããŠãæžã蟌ã¿ã«å€§ããªæéãèŠããŠã¯ãªããŸããã ã³ãŒãã®ãã¹ãã«ã³ãŒãã®èšè¿°ãšæ¯èŒããŠæéããããããšã倿ããå Žåã¯ããããã¹ãå¯èœãªèšèšãæ€èšããŠãã ããã
ã³ãŒãã«ãã¬ããžãšã³ãŒãå質
å€ãã®å Žåãã³ãŒã ã«ãã¬ããžã®å²åãé«ããšãã³ãŒãã®å質ãåäžããŸãã ãã ããæž¬å®èªäœã¯ã³ãŒãã®å質ã倿 ã§ããŸãã ã é床ã«éå¿çãªã³ãŒã ã«ãã¬ããžçã®ç®æšãèšå®ãããšãé广ã«ãªãå¯èœæ§ããããŸãã äœåãã®æ¡ä»¶ä»ãåå²ãå«ãè€éãªãããžã§ã¯ãã«ã€ããŠèããŠã95% ã³ãŒã ã«ãã¬ããžã®ç®æšãèšå®ãããšããŸãã çŸåšããã®ãããžã§ã¯ã㯠90% ã®ã³ãŒã ã«ãã¬ããžãç¶æããŠããŸãã æ®ãã® 5% ã®ãã¹ãŠã®ãšããž ã±ãŒã¹ãèæ ®ã«å ¥ããã®ã«ãããæéã¯èšå€§ãªäœæ¥ã«ãªããäŸ¡å€ææ¡ã¯ããã«æžå°ããŸãã
ã³ãŒãã«ãã¬ããžã®å²åãé«ããŠãããããæåã®ææšã§ãããšã¯éãããã³ãŒãã®å質ãé«ãããšãæå³ããããã§ã¯ãããŸããã åäœãã¹ãã§ã«ããŒãããã³ãŒãã®éã衚ãã ãã§ãã 詳现ã«ã€ããŠã¯ã åäœãã¹ãã®ã³ãŒã ã«ãã¬ããžã«é¢ããèšäºãåç §ããŠãã ããã
åäœãã¹ãã®çšèª
åäœãã¹ãã®ã³ã³ããã¹ãã§ã¯ã åœã ã¢ãã¯ã ã¹ã¿ããªã©ãããã€ãã®çšèªãé »ç¹ã«äœ¿çšãããŸãã æ®å¿µãªããããããã®çšèªã¯èª€ã£ãŠé©çšãããå¯èœæ§ããããããæ£ããäœ¿çšæ¹æ³ãçè§£ããããšãéèŠã§ãã
泚
æç®ãããŒã«ã®ãã¹ãã§ã¯ã åœç©ã ã¹ã¿ãã ã¢ã㯠ãšããçšèªãççŸããŠäœ¿çšãããŸãã æ¬¡ã®å®çŸ©ã¯ããã¹ã ããã«ãå€ãè¿ããçžäºäœçšãæ€èšŒã§ããäžè¬çãª.NETäœ¿çšæ³ã衚ããŠããŸãã åŸæ¥ã® xUnit ãšãã¹ãã®äºéæç® (Fowler ã Meszaros ãªã©) ã§ã¯ããããã®ãœãŒã¹ã§ã¯ããããã®åèªãããçã䜿çšããŸãã ã¹ã¿ã ã¯ããŒã¿ãæäŸãã ã¢ã㯠ã¯çžäºäœçšãæ€èšŒãã åœç© ã¯å®éã®ä»£æ¿å®è£ ã§ãã
åœç©: åœç©ã¯ãã¹ã¿ããŸãã¯ã¢ã㯠ãªããžã§ã¯ããèšè¿°ããããã«äœ¿çšã§ããäžè¬çãªçšèªã§ãã ãªããžã§ã¯ããã¹ã¿ããã¢ãã¯ãã¯ããªããžã§ã¯ãã䜿çšãããã³ã³ããã¹ãã«ãã£ãŠç°ãªããŸãã ã€ãŸãããã§ã€ã¯ã¯ã¹ã¿ããšã¢ãã¯ã®ã©ã¡ãã«ããªãããŸãã
ã¢ãã¯: ã¢ã㯠ãªããžã§ã¯ãã¯ãåäœãã¹ãã«åæ Œããã倱æããããæ±ºå®ããã·ã¹ãã å ã®åœã®ãªããžã§ã¯ãã§ãã ã¢ãã¯ã¯æåããåœç©ã§ããã
Assertæäœã«å ¥ããŸã§ãã®ç¶æ ã®ãŸãŸã§ããã¹ã¿ã: ã¹ã¿ãã¯ãã·ã¹ãã å ã®æ¢åã®äŸåé¢ä¿ (ãŸãã¯ã³ã©ãã¬ãŒã¿ãŒ) ã®å¶åŸ¡å¯èœãªä»£æ¿ã§ãã ã¹ã¿ãã䜿çšãããšãäŸåé¢ä¿ãçŽæ¥åŠçããã«ã³ãŒãããã¹ãã§ããŸãã æ¢å®ã§ã¯ãã¹ã¿ãã¯æåã¯ãã§ã€ã¯ãšããŠæ©èœããŸãã
次ã®ã³ãŒãã«ã€ããŠèããŠã¿ãŸãããã
var mockOrder = new MockOrder();
var purchase = new Purchase(mockOrder);
purchase.ValidateOrders();
Assert.True(purchase.CanBeShipped);
ãã®ã³ãŒãã¯ãã¢ãã¯ãšåŒã°ããã¹ã¿ãã瀺ããŠããŸãã ãããããã®ã·ããªãªã§ã¯ãã¹ã¿ãã¯çŽç²ã«ã¹ã¿ããšããŠã®ã¿æ©èœããŸãã ã³ãŒãã®ç®çã¯ã Purchase (ãã¹ã察象ã®ã·ã¹ãã ) ãªããžã§ã¯ããã€ã³ã¹ã¿ã³ã¹åããææ®µãšããŠé åºãæž¡ãããšã§ãã é åºã¯ã¹ã¿ãã§ãããã¢ãã¯ã§ã¯ãªããããã¯ã©ã¹å MockOrder ã¯èª€è§£ãæããŸãã
次ã®ã³ãŒãã¯ãããæ£ç¢ºãªèšèšã瀺ããŠããŸãã
var stubOrder = new FakeOrder();
var purchase = new Purchase(stubOrder);
purchase.ValidateOrders();
Assert.True(purchase.CanBeShipped);
ã¯ã©ã¹ã®ååã FakeOrder ã«å€æŽãããšãã¯ã©ã¹ã¯ããæ±çšçã«ãªããŸãã ãã®ã¯ã©ã¹ã¯ããã¹ã ã±ãŒã¹ã®èŠä»¶ã«åŸã£ãŠãã¢ãã¯ãŸãã¯ã¹ã¿ããšããŠäœ¿çšã§ããŸãã æåã®äŸã§ã¯ã FakeOrder ã¯ã©ã¹ã¯ã¹ã¿ããšããŠäœ¿çšããã Assert æäœäžã¯äœ¿çšãããŸããã ãã®ã³ãŒãã¯ãã³ã³ã¹ãã©ã¯ã¿ãŒã®èŠä»¶ãæºããããã«ã FakeOrder ã¯ã©ã¹ã Purchase ã¯ã©ã¹ã«æž¡ããŸãã
ãã®ã¯ã©ã¹ãã¢ãã¯ãšããŠäœ¿çšããã«ã¯ãã³ãŒããæŽæ°ããŸãã
var mockOrder = new FakeOrder();
var purchase = new Purchase(mockOrder);
purchase.ValidateOrders();
Assert.True(mockOrder.Validated);
ãã®èšèšã§ã¯ãã³ãŒãã¯åœç©ã®ããããã£ããã§ãã¯ããŸã (ããã«å¯ŸããŠã¢ãµãŒããã)ããããã£ãŠã mockOrder ã¯ã©ã¹ã¯ã¢ãã¯ã§ãã
Von Bedeutung
çšèªãæ£ããå®è£ ããããšãéèŠã§ãã ã¹ã¿ãã "ã¢ãã¯" ãšåŒã¶ãšãä»ã®éçºè ãæå³ã«ã€ããŠèª€ã£ãæ³å®ãè¡ãäºå®ã§ãã
ã¢ãã¯ãšã¹ã¿ãã«ã€ããŠèŠããŠããã¹ãäž»ãªç¹ã¯ãã¢ãã¯ã¯ Assert ããã»ã¹ãé€ããŠãã¹ã¿ããšåãããšã§ãã ã¢ã㯠ãªããžã§ã¯ãã«å¯Ÿã㊠Assert æäœãå®è¡ããŸãããã¹ã¿ãã«å¯ŸããŠå®è¡ããããšã¯ã§ããŸããã
ãã¹ã ãã©ã¯ãã£ã¹
åäœãã¹ããèšè¿°ãããšãã¯ãããã€ãã®éèŠãªãã¹ã ãã©ã¯ãã£ã¹ã«åŸãå¿ èŠããããŸãã æ¬¡ã®ã»ã¯ã·ã§ã³ã§ã¯ãã³ãŒãã«ãã¹ã ãã©ã¯ãã£ã¹ãé©çšããæ¹æ³ã瀺ãäŸã瀺ããŸãã
ã€ã³ãã©ã¹ãã©ã¯ãã£ã®äŸåé¢ä¿ãåé¿ãã
åäœãã¹ãã®äœææã«ã€ã³ãã©ã¹ãã©ã¯ãã£ã«äŸåé¢ä¿ãå°å ¥ããªãããã«ããŠãã ããã äŸåé¢ä¿ã«ããããã¹ãã¯é ããè匱ã«ãªããçµ±åãã¹ãçšã«äºçŽããå¿ èŠããããŸãã ã¢ããªã±ãŒã·ã§ã³ã§ãããã®äŸåé¢ä¿ãåé¿ããã«ã¯ãExplicit äŸåé¢ä¿ã®ååã«åŸãã.NETäŸåé¢ä¿ã®æ¿å ¥ã䜿çšããŸãã çµ±åãã¹ããšã¯å¥ã®ãããžã§ã¯ãã«åäœãã¹ããä¿æããããšãã§ããŸãã ãã®æ¹æ³ã«ãããåäœãã¹ã ãããžã§ã¯ããã€ã³ãã©ã¹ãã©ã¯ã㣠ããã±ãŒãžãžã®åç §ãäŸåé¢ä¿ãæããªãããã«ããŸãã
ãã¹ãã®ååä»ãæšæºã«åŸã
ãã¹ãã®ååã¯ã次㮠3 ã€ã®éšåã§æ§æãããŠããå¿ èŠããããŸãã
- ãã¹ã察象ã®ã¡ãœããã®åå
- ã¡ãœããããã¹ããããŠããã·ããªãª
- ã·ããªãªãåŒã³åºããããšãã®äºæãããåäœ
ãã¹ã察象ã®ã³ãŒãã®äºæãããåäœãææžåããã«ã¯ãããããããäžè²«æ§ã®ãããã¹ãåã䜿çšããŸãã åãã¹ãåã¯ãç¹å®ã®ã·ããªãªã§ã³ãŒããã©ã®ããã«åäœãã¹ãããæå®ãããã¹ãã¯ãã®åäœãæ€èšŒããŸãã æç¢ºãªååã¯ããã¹ã察象ã®ã³ãŒãã調ã¹ãã«ããã¹ã ã¹ã€ãŒãããã®æ³å®ãããåäœãçè§£ããã®ã«åœ¹ç«ã¡ãŸãã ãã¹ãã倱æããå Žåããã®ååã¯ãæåŸ ãæºãããŠããªãã·ããªãªãç¹å®ããã®ã«åœ¹ç«ã¡ãŸãã
å ã®ã³ãŒã
[Fact]
public void Test_Single()
{
var stringCalculator = new StringCalculator();
var actual = stringCalculator.Add("0");
Assert.Equal(0, actual);
}
ãã¹ã ãã©ã¯ãã£ã¹ãé©çšãã
[Fact]
public void Add_SingleNumber_ReturnsSameNumber()
{
var stringCalculator = new StringCalculator();
var actual = stringCalculator.Add("0");
Assert.Equal(0, actual);
}
ãã¹ããé 眮ãã
"æºåãè¡åãæ€èšŒ" ãã¿ãŒã³ã¯ãåäœãã¹ããèšè¿°ããããã®äžè¬çãªã¢ãããŒãã§ãã ååã瀺ãããã«ããã¿ãŒã³ã¯æ¬¡ã® 3 ã€ã®äž»èŠãªã¿ã¹ã¯ã§æ§æãããŸãã
- ãªããžã§ã¯ããé 眮ããå¿ èŠã«å¿ããŠäœæããæ§æãã
- ãªããžã§ã¯ãã«å¯ŸããŠæäœãã
- äœããæåŸ ã©ããã«ãªã£ãŠããããšãã¢ãµãŒããã
ãã¿ãŒã³ã«åŸããšããã¹ã察象ãé 眮ã¿ã¹ã¯ãš Assert ã¿ã¹ã¯ããæç¢ºã«åé¢ã§ããŸãã ãã®ãã¿ãŒã³ã¯ãAct ã¿ã¹ã¯ã®ã³ãŒããšã¢ãµãŒã·ã§ã³ãæ··åšããæ©äŒãæžããã®ã«ã圹ç«ã¡ãŸãã
èªã¿ãããã¯ãåäœãã¹ããèšè¿°ãããšãã®æãéèŠãªåŽé¢ã® 1 ã€ã§ãã ãã¹ãå ã§åãã¿ãŒã³ ã¢ã¯ã·ã§ã³ãåé¢ãããšãã³ãŒãã®åŒã³åºãã«å¿ èŠãªäŸåé¢ä¿ãã³ãŒãã®åŒã³åºãæ¹æ³ãã¢ãµãŒãããããšããŠããå 容ãæç¢ºã«åŒ·èª¿è¡šç€ºãããŸãã ããã€ãã®æé ãçµã¿åãããŠãã¹ãã®ãµã€ãºãå°ããããããšã¯å¯èœã§ãããå šäœçãªç®æšã¯ããã¹ããå¯èœãªéãèªã¿ãããããããšã§ãã
å ã®ã³ãŒã
[Fact]
public void Add_EmptyString_ReturnsZero()
{
// Arrange
var stringCalculator = new StringCalculator();
// Assert
Assert.Equal(0, stringCalculator.Add(""));
}
ãã¹ã ãã©ã¯ãã£ã¹ãé©çšãã
[Fact]
public void Add_EmptyString_ReturnsZero()
{
// Arrange
var stringCalculator = new StringCalculator();
// Act
var actual = stringCalculator.Add("");
// Assert
Assert.Equal(0, actual);
}
æå°éã®æ å ±ã§åæ Œãããã¹ããèšè¿°ãã
åäœãã¹ãã®å ¥åã¯ãçŸåšãã¹ãããŠããåäœã確èªããããã«å¿ èŠãªæãç°¡åãªæ å ±ã§ããå¿ èŠããããŸãã æå°éã®ã¢ãããŒãã¯ãã³ãŒãããŒã¹ã®å°æ¥ã®å€æŽã«å¯Ÿãããã¹ãã®å埩åãé«ããå®è£ ã«å¯Ÿããåäœã®æ€èšŒã«çŠç¹ãåœãŠãã®ã«åœ¹ç«ã¡ãŸãã
çŸåšã®ãã¹ãã«åæ Œããããã«å¿ èŠä»¥äžã®æ å ±ãå«ããã¹ãã§ã¯ããã¹ãã«ãšã©ãŒãçºçããå¯èœæ§ãé«ããªãããã¹ãã®æå³ãæç¢ºã§ãªããªãå¯èœæ§ããããŸãã ãã¹ããèšè¿°ãããšãã¯ãåäœã«çŠç¹ãåœãŠãå¿ èŠããããŸãã ã¢ãã«ã«è¿œå ã®ããããã£ãèšå®ããããšããå¿ èŠãªãå Žåã«0以å€ã®å€ã䜿çšããããšã¯ã確èªããããšããŠããå 容ãæãªãã ãã§ãã
å ã®ã³ãŒã
[Fact]
public void Add_SingleNumber_ReturnsSameNumber()
{
var stringCalculator = new StringCalculator();
var actual = stringCalculator.Add("42");
Assert.Equal(42, actual);
}
ãã¹ã ãã©ã¯ãã£ã¹ãé©çšãã
[Fact]
public void Add_SingleNumber_ReturnsSameNumber()
{
var stringCalculator = new StringCalculator();
var actual = stringCalculator.Add("0");
Assert.Equal(0, actual);
}
éæ³ã®æååãé¿ãã
ããžãã¯æåå ã¯ãã³ãŒãã®è¿œå ã³ã¡ã³ããã³ã³ããã¹ããªãã§ãåäœãã¹ãã§çŽæ¥ããŒãã³ãŒãã£ã³ã°ãããæååå€ã§ãã ãããã®å€ã«ãããã³ãŒãã®èªã¿ããããäœäžããä¿å®ãå°é£ã«ãªããŸãã ããžãã¯æååã¯ããã¹ãã®ãªãŒããŒã«æ··ä¹±ãåŒãèµ·ããå¯èœæ§ããããŸãã æååãéåžžã®å€ããå€ããŠããå Žåããã©ã¡ãŒã¿ãŒãŸãã¯æ»ãå€ã«å¯ŸããŠç¹å®ã®å€ãéžæãããçç±ãçåã«æããããããŸããã ãã®çš®é¡ã®æååå€ã¯ããã¹ãã«çŠç¹ãåœãŠãã®ã§ã¯ãªããå®è£ ã®è©³çްã詳ãã調ã¹ãããã«ãªãå¯èœæ§ããããŸãã
ãã³ã
åäœãã¹ã ã³ãŒãã§ã§ããã ãå€ãã®æå³ã衚çŸããããšãç®æšã«ããŸãã ããžãã¯æååã䜿çšããã®ã§ã¯ãªããããŒãã³ãŒãã£ã³ã°ãããå€ã宿°ã«å²ãåœãŠãŸãã
å ã®ã³ãŒã
[Fact]
public void Add_BigNumber_ThrowsException()
{
var stringCalculator = new StringCalculator();
Action actual = () => stringCalculator.Add("1001");
Assert.Throws<OverflowException>(actual);
}
ãã¹ã ãã©ã¯ãã£ã¹ãé©çšãã
[Fact]
void Add_MaximumSumResult_ThrowsOverflowException()
{
var stringCalculator = new StringCalculator();
const string MAXIMUM_RESULT = "1001";
Action actual = () => stringCalculator.Add(MAXIMUM_RESULT);
Assert.Throws<OverflowException>(actual);
}
åäœãã¹ãã§ã®ã³ãŒãã£ã³ã° ããžãã¯ã®åé¿
åäœãã¹ããèšè¿°ãããšãã¯ãæåã§ã®æååé£çµã ifã whileã forã switchãªã©ã®è«çæ¡ä»¶ãããã³ãã®ä»ã®æ¡ä»¶ã¯é¿ããŠãã ããã ãã¹ã ã¹ã€ãŒãã«ããžãã¯ãå«ããå Žåããã°ãçºçããå¯èœæ§ã倧å¹
ã«é«ããªããŸãã ãã°ãèŠã€ããæåŸã®å Žæã¯ããã¹ã ã¹ã€ãŒãå
ã«ãããŸãã ãã¹ããæ©èœããé«ãã¬ãã«ã®ä¿¡é ŒåºŠãå¿
èŠã§ãããã以å€ã®å Žåã¯ãããããä¿¡é Œã§ããŸããã ä¿¡é Œã§ããªããã¹ãã§ã¯ãå€ã¯æäŸãããŸããã ãã¹ãã倱æããå Žåãã³ãŒãã«åé¡ããããç¡èŠã§ããªããšããæèŠãå¿
èŠã§ãã
ãã³ã
ãã¹ãã«ããžãã¯ã远å ããã®ã¯é¿ããããªããšæãããå Žåã¯ãããžãã¯èŠä»¶ãå¶éããããã«ããã¹ãã 2 ã€ä»¥äžã®ç°ãªããã¹ãã«åå²ããããšãæ€èšããŠãã ããã
å ã®ã³ãŒã
[Fact]
public void Add_MultipleNumbers_ReturnsCorrectResults()
{
var stringCalculator = new StringCalculator();
var expected = 0;
var testCases = new[]
{
"0,0,0",
"0,1,2",
"1,2,3"
};
foreach (var test in testCases)
{
Assert.Equal(expected, stringCalculator.Add(test));
expected += 3;
}
}
ãã¹ã ãã©ã¯ãã£ã¹ãé©çšãã
[Theory]
[InlineData("0,0,0", 0)]
[InlineData("0,1,2", 3)]
[InlineData("1,2,3", 6)]
public void Add_MultipleNumbers_ReturnsSumOfNumbers(string input, int expected)
{
var stringCalculator = new StringCalculator();
var actual = stringCalculator.Add(input);
Assert.Equal(expected, actual);
}
åæåãšãã£ã¢ããŠã³ã®ä»£ããã«ãã«ããŒã¡ãœããã䜿çšãã
ãã¹ãåºæã®ã»ããã¢ãããæç€ºããŠããã«ã¯ãåãã¹ã ã¡ãœããã«å¿
èŠãªãªããžã§ã¯ããäœæãããããã¹ããããã«ã㌠ã¡ãœãããåŒã³åºãã ãã¹ãã®ã»ããã¢ããèŠä»¶ãç°ãªãå Žåã¯ãSetup 屿§ã Teardown 屿§ã§ã¯ãªãããã®ã¢ãããŒããåªå
ããŸãã
- åãã¹ãã«ã¯ãå¿ èŠãªã»ããã¢ããã瀺ãããŸãã
- åãã¹ãã§ã¯ãå¿ èŠãªãªããžã§ã¯ããšç¶æ ã®ã¿ãäœæãããŸãã
- äžè¬çãªã»ããã¢ãã ã³ãŒãã«å¯Ÿãã倿Žã¯ãããã䜿çšããªããã¹ãã«ã¯åœ±é¿ããŸããã
ãã¹ãããšã®ã»ããã¢ãã ã¡ãœããã¯ããã¹ãã§ãã¹ãŠã®ã»ããã¢ãããå¿ èŠãªãå Žåã§ããã¹ã³ãŒãå ã®ãã¹ãŠã®ãã¹ãã®åã«å®è¡ãããŸãã ãã¹ãããšã«å¿ èŠæ¡ä»¶ãç°ãªãã«ã€ããŠãäžè¬çãªã»ããã¢ããæ¹æ³ã§äžèŠãªãªããžã§ã¯ããäœæããããç¹å®ã®ãã¹ããäŸåããç¶æ ãèŠãã«ãããããããããšããããŸãã
ã¯ã©ã¹å
ã®ãã¹ãŠã®ãã¹ãã§åãåæåãå¿
èŠãªå Žåã¯ãå
±éã®ãã¹ãããšã®ã»ããã¢ãããåŒãç¶ãé©åã§ãã ããšãã°ãMSTest ã§ã¯ãåããŒã¿è¡ãå«ããã¹ãããšã«æ°ãããã¹ã ã¯ã©ã¹ ã€ã³ã¹ã¿ã³ã¹ãäœæããããããã³ã³ã¹ãã©ã¯ã¿ãŒã®åæåã¯ãã¹ãããšã«åå¥ã«å®è¡ãããŸãã åæåæåã®å Žåã¯ãã³ã³ã¹ãã©ã¯ã¿ãŒãåªå
ããŸãã éåæåæåãŸãã¯ã¿ã€ã ã¢ãŠãã®ãµããŒããå¿
èŠãªå Žåã¯ã TestInitialize ã䜿çšããŸãã 詳现ã«ã€ããŠã¯ã MSTest ã®ã©ã€ããµã€ã¯ã«ãåç
§ããŠãã ããã
泚
SetUp屿§ãšTearDown屿§ã¯ãxUnit ããŒãžã§ã³ 2.x 以éã§ã¯åé€ãããŸãã
å ã®ã³ãŒã
ãã¹ã ãã©ã¯ãã£ã¹ãé©çšãã
private readonly StringCalculator stringCalculator;
public StringCalculatorTests()
{
stringCalculator = new StringCalculator();
}
[Fact]
public void Add_TwoNumbers_ReturnsSumOfNumbers()
{
var stringCalculator = CreateDefaultStringCalculator();
var actual = stringCalculator.Add("0,1");
Assert.Equal(1, actual);
}
// More tests...
// More tests...
[Fact]
public void Add_TwoNumbers_ReturnsSumOfNumbers()
{
var result = stringCalculator.Add("0,1");
Assert.Equal(1, result);
}
private StringCalculator CreateDefaultStringCalculator()
{
return new StringCalculator();
}
è€æ°ã® Act ã¿ã¹ã¯ãåé¿ãã
ãã¹ããèšè¿°ãããšãã¯ããã¹ãããšã« 1 ã€ã® Act ã¿ã¹ã¯ã®ã¿ãå«ããŠã¿ãŠãã ããã 1 ã€ã® Act ã¿ã¹ã¯ãå®è£ ããããã®äžè¬çãªæ¹æ³ãšããŠã¯ãAct ããšã«åå¥ã®ãã¹ããäœæãããããã©ã¡ãŒã¿ãŒåããããã¹ãã䜿çšãããããæ¹æ³ããããŸãã ãã¹ãããšã« 1 ã€ã® Act ã¿ã¹ã¯ã䜿çšãããšãããã€ãã®å©ç¹ããããŸãã
- ãã¹ãã倱æããå Žåã«å€±æããŠãã Act ã¿ã¹ã¯ãç°¡åã«èå¥ã§ããŸãã
- ãã¹ãã 1 ã€ã®ã±ãŒã¹ã®ã¿ã«éäžããŠããããšã確èªã§ããŸãã
- ãã¹ãã倱æããçç±ãæç¢ºã«ææ¡ã§ããŸãã
è€æ°ã® Act ã¿ã¹ã¯ãåå¥ã«ã¢ãµãŒãããå¿ èŠãããããã¹ãŠã® Assert ã¿ã¹ã¯ãå®è¡ãããããšãä¿èšŒããããšã¯ã§ããŸããã ã»ãšãã©ã®åäœãã¹ã ãã¬ãŒã ã¯ãŒã¯ã§ã¯ãåäœãã¹ãã§ Assert ã¿ã¹ã¯ã倱æããåŸãåŸç¶ã®ãã¹ãŠã®ãã¹ãã¯èªåçã«å€±æãšèŠãªãããŸãã äžéšã®æ©èœã倱æãšè§£éãããå¯èœæ§ãããããããã®ããã»ã¹ã¯æ··ä¹±ããå¯èœæ§ããããŸãã
å ã®ã³ãŒã
[Fact]
public void Add_EmptyEntries_ShouldBeTreatedAsZero()
{
// Act
var actual1 = stringCalculator.Add("");
var actual2 = stringCalculator.Add(",");
// Assert
Assert.Equal(0, actual1);
Assert.Equal(0, actual2);
}
ãã¹ã ãã©ã¯ãã£ã¹ãé©çšãã
[Theory]
[InlineData("", 0)]
[InlineData(",", 0)]
public void Add_EmptyEntries_ShouldBeTreatedAsZero(string input, int expected)
{
// Arrange
var stringCalculator = new StringCalculator();
// Act
var actual = stringCalculator.Add(input);
// Assert
Assert.Equal(expected, actual);
}
ãããªã㯠ã¡ãœããã䜿çšããŠãã©ã€ããŒã ã¡ãœãããæ€èšŒãã
ã»ãšãã©ã®å Žåãã³ãŒãã§ãã©ã€ããŒã ã¡ãœããããã¹ãããå¿ èŠã¯ãããŸããã ãã©ã€ããŒã ã¡ãœããã¯å®è£ ã®è©³çްã§ãããåç¬ã§ã¯ååšããŸããã éçºããã»ã¹ã®ããæç¹ã§ãå®è£ ã®äžéšãšããŠãã©ã€ããŒã ã¡ãœãããåŒã³åºãå ¬éã¡ãœãããå°å ¥ããŸãã åäœãã¹ããèšè¿°ãããšãã«æ°ã«ãªãã®ã¯ããã©ã€ããŒã ã¡ãœãããåŒã³åºããããªã㯠ã¡ãœããã®æçµçãªçµæã§ãã
次ã®ã³ãŒã ã·ããªãªãèããŠã¿ãŸãããã
public string ParseLogLine(string input)
{
var sanitizedInput = TrimInput(input);
return sanitizedInput;
}
private string TrimInput(string input)
{
return input.Trim();
}
ãã¹ãã®èгç¹ãããæåã®åå¿ã¯ã TrimInput ã¡ãœãããæåŸ
ã©ããã«åäœããããšã確èªããããã®ãã¹ããèšè¿°ããããšã§ãã ãã ãã ParseLogLine ã¡ãœãããäºæããªãæ¹æ³ã§ sanitizedInput ãªããžã§ã¯ããæäœããå¯èœæ§ããããŸãã äžæãªåäœã«ããã TrimInput ã¡ãœããã«å¯Ÿãããã¹ãã圹ã«ç«ããªãå¯èœæ§ããããŸãã
ãã®ã·ããªãªã®ããè¯ããã¹ãã¯ãäžè¬åãã® ParseLogLine ã¡ãœããã確èªããããšã§ãã
public void ParseLogLine_StartsAndEndsWithSpace_ReturnsTrimmedResult()
{
var parser = new Parser();
var result = parser.ParseLogLine(" a ");
Assert.Equals("a", result);
}
ãã©ã€ããŒã ã¡ãœãããçºçãããããã©ã€ããŒã ã¡ãœãããåŒã³åºããããªã㯠ã¡ãœãããèŠã€ãããããªã㯠ã¡ãœããã«å¯ŸããŠãã¹ããèšè¿°ããŸãã ãã©ã€ããŒã ã¡ãœãããäºæããçµæãè¿ããããšãã£ãŠãæçµçã«ãã©ã€ããŒã ã¡ãœãããåŒã³åºãã·ã¹ãã ã§çµæãæ£ãã䜿çšãããããã§ã¯ãããŸããã
ã·ãŒã ã«ããã¹ã¿ãã®éçåç §ãåŠçãã
åäœãã¹ãã®ååã® 1 ã€ã¯ããã¹ã察象ã®ã·ã¹ãã ãå®å
šã«å¶åŸ¡ããå¿
èŠããããšããããšã§ãã ãã ããéçšç°å¢ã®ã³ãŒãã«éçåç
§ã®åŒã³åºã ( DateTime.Now ãªã©) ãå«ãŸããŠããå Žåããã®ååã¯åé¡ã«ãªãå¯èœæ§ããããŸãã
次ã®ã³ãŒã ã·ããªãªã確èªããŸãã
public int GetDiscountedPrice(int price)
{
if (DateTime.Now.DayOfWeek == DayOfWeek.Tuesday)
{
return price / 2;
}
else
{
return price;
}
}
ãã®ã³ãŒãã®åäœãã¹ããèšè¿°ã§ããŸãã?
priceã§ Assert ã¿ã¹ã¯ãå®è¡ããŠã¿ãŠãã ããã
public void GetDiscountedPrice_NotTuesday_ReturnsFullPrice()
{
var priceCalculator = new PriceCalculator();
var actual = priceCalculator.GetDiscountedPrice(2);
Assert.Equals(2, actual)
}
public void GetDiscountedPrice_OnTuesday_ReturnsHalfPrice()
{
var priceCalculator = new PriceCalculator();
var actual = priceCalculator.GetDiscountedPrice(2);
Assert.Equals(1, actual);
}
æ®å¿µãªããããã¹ãã«åé¡ãããããšã«ããã«æ°ä»ããŸãã
- ãã¹ã ã¹ã€ãŒããç«ææ¥ã«å®è¡ãããå Žåã2 çªç®ã®ãã¹ãã¯æåããŸãããæåã®ãã¹ãã¯å€±æããŸãã
- ãã¹ã ã¹ã€ãŒããä»ã®æ¥ã«å®è¡ãããå Žåãæåã®ãã¹ãã¯æåããŸããã2 çªç®ã®ãã¹ãã¯å€±æããŸãã
ãããã®åé¡ã解決ããã«ã¯ãéçšã³ãŒãã« ç¶ãç® ãå°å ¥ããå¿ èŠããããŸãã 1 ã€ã®æ¹æ³ã¯ãã€ã³ã¿ãŒãã§ã€ã¹ã§å¶åŸ¡ããå¿ èŠãããã³ãŒããã©ããããéçšã³ãŒãããã®ã€ã³ã¿ãŒãã§ã€ã¹ã«äŸåããããã«ããããšã§ãã
public interface IDateTimeProvider
{
DayOfWeek DayOfWeek();
}
public int GetDiscountedPrice(int price, IDateTimeProvider dateTimeProvider)
{
if (dateTimeProvider.DayOfWeek() == DayOfWeek.Tuesday)
{
return price / 2;
}
else
{
return price;
}
}
ãŸãããã¹ã ã¹ã€ãŒãã®æ°ããããŒãžã§ã³ãèšè¿°ããå¿ èŠããããŸãã
public void GetDiscountedPrice_NotTuesday_ReturnsFullPrice()
{
var priceCalculator = new PriceCalculator();
var dateTimeProviderStub = new Mock<IDateTimeProvider>();
dateTimeProviderStub.Setup(dtp => dtp.DayOfWeek()).Returns(DayOfWeek.Monday);
var actual = priceCalculator.GetDiscountedPrice(2, dateTimeProviderStub);
Assert.Equals(2, actual);
}
public void GetDiscountedPrice_OnTuesday_ReturnsHalfPrice()
{
var priceCalculator = new PriceCalculator();
var dateTimeProviderStub = new Mock<IDateTimeProvider>();
dateTimeProviderStub.Setup(dtp => dtp.DayOfWeek()).Returns(DayOfWeek.Tuesday);
var actual = priceCalculator.GetDiscountedPrice(2, dateTimeProviderStub);
Assert.Equals(1, actual);
}
ããã§ããã¹ã ã¹ã€ãŒã㯠DateTime.Now å€ãå®å
šã«å¶åŸ¡ã§ããããã«ãªããã¡ãœãããåŒã³åºããšãã«ä»»æã®å€ãã¹ã¿ãã§ããŸãã