'Class.ReceivedCallsïŒïŒ'ããã³ 'var tmp = Class.ReceivedïŒintïŒ.Property;'ã䜿çšããå€ãã®ãã¹ãããããŸãã é話æ°ã確èªããŸãã AutoFixtureã®v3ã§ã¯ãç¹ã«ããããã£ã®åŒã³åºãæ°ãæ£ããå ±åãããŸããããããã¯ããè¡ãããŸããã ã¡ãœããã®åŒã³åºãæ°ã¯ãŸã åé¡ãªãããã§ãã
次ã®ã³ãŒãããããšããŸãã
public interface IRunSpeed
{
int Speed { get; }
}
public class GetToDaChoppa
{
private readonly IRunSpeed _runSpeed;
public GetToDaChoppa(IRunSpeed runSpeed)
{
_runSpeed = runSpeed ?? throw new ArgumentNullException(nameof(runSpeed));
}
public void DoItNow()
{
var runningSpeed = _runSpeed.Speed;
}
}
ãããŠã次ã®ãã¹ãããããšä»®å®ããŸãã
[Fact]
public void DoItNow_WithOutAutoNSubstitute()
{
// Arrange
var runSpeed = Substitute.For<IRunSpeed>();
runSpeed.Speed.Returns(2);
var sut = new GetToDaChoppa(runSpeed);
//Act
sut.DoItNow();
//Assert
var tmp = runSpeed.Received(1).Speed;
Assert.Single(runSpeed.ReceivedCalls());
}
[Theory, AutoNSubstituteData]
public void DoItNow_UsingAutoNSubstitute(
[Frozen] IRunSpeed runSpeed,
GetToDaChoppa sut)
{
// Arrange
runSpeed.Speed.Returns(49);
//Act
sut.DoItNow();
//Assert
var tmp = runSpeed.Received(1).Speed;
Assert.Single(runSpeed.ReceivedCalls());
ç§ã®AutoNSubstituteDataAttributeã¯æ¬¡ã®ããã«ãªããŸãã
public class AutoNSubstituteDataAttribute : AutoDataAttribute
{
public AutoNSubstituteDataAttribute()
: base(() => new Fixture()
.Customize(new AutoNSubstituteCustomization()))
{
}
}
æåã®ãã¹ããDoItNow_WithOutAutoNSubstituteãã¯æ£åžžã«æ©èœããŠããŸãã ãã ãã2çªç®ã®ãã¹ããDoItNow_UsingAutoNSubstituteãã¯ãios.ReceivedïŒ1ïŒ.Speed;ãã«å¯ŸããŠ2ãè¿ããŸãã
ãŸãã 'runSpeed.ReceivedCallsïŒïŒ;'ã«å¯ŸããŠ2ãè¿ããŸãã
ãã®ããããœãªã¥ãŒã·ã§ã³ããšã«1000ãè¶
ãã倱æãããã¹ããå³åº§ã«çºçãããããçŸåšããœãªã¥ãŒã·ã§ã³ãv4ã«ã¢ããã°ã¬ãŒãããããšã¯ã§ããŸããã åé¡ãäœã§ãããããŸãã¯ã©ãã§ä¿®æ£ãæ¢ãã¹ããã«ã€ããŠã®ã¬ã€ãã³ã¹ã¯ãããŸããïŒ
åé¡ãçºçãããŠããã ãããããšãããããŸãã å®éããã®åé¡ã¯AutoFixtureãšã¯é¢ä¿ãããŸããããAutoFixtureã®åœ±é¿ãåããŸãð
ãã®åé¡ã¯äž»ã«xUnitãåå ã§çºçãããã¹ãã次ã®ããã«æžãçŽããšãåæ ŒããŸãã
`` `cïŒ
[çè«ãAutoNSubstituteData]
public void DoItNow_UsingAutoNSubstitute_CreateManuallyïŒIFixtureãã£ã¯ã¹ãã£ïŒ
{{
// æŽãã
var runSpeed = fixture.Freeze
var sut = fixture.Create
runSpeed.Speed.ReturnsïŒ49ïŒ;
//Act
sut.DoItNow();
//Assert
var tmp = runSpeed.Received(1).Speed;
Assert.Single(runSpeed.ReceivedCalls());
}
`` `
ãã¹ããå®è¡ãããšãxUnitã¯ãã¹ãåããã©ãŒãããããããšããŸãã ã¿ã€ããäžæã§ã ToString()
ãªãŒããŒããŒãããªãããšãããã£ãå Žåãæ§é æ€æ»ã䜿çšããŠãããããã£å€ãååž°çã«ãã§ããããŸãã ãã¹ãåã確èªãããšã次ã®ããã«è¡šç€ºãããŸãã
ãæ°ã¥ããããããŸããããxUnitã¯Speed
ããããã£å€ããã§ããããŠããã¹ãåŒæ°ãé©åã«è¡šç€ºããŸãã ããã¯éåžžã®åŒã³åºãã§ãããããNSubstituteã¯ãããåŒã³åºããšããŠã«ãŠã³ãããŸããã
ãã®ç¹ã§äœãå€ãã£ãŠããªãã®ã§ãv3ã§ãã®åé¡ãçºçããªãã£ãã®ã¯éåžžã«å¥åŠã§ãã xUnit2 + AutoFixture v3
ããã¹ããããšããããŸã åé¡ãçºçããŠããŸãã ãããããxUnitãã¢ããã°ã¬ãŒãããŸããã
åé¿çã«ã€ããŠã¯ãè¯ããã¥ãŒã¹ãšæªããã¥ãŒã¹ããããŸãã è¯ããã¥ãŒã¹ã¯ããããã·IDãè¿ãããã«ToString()
ã¡ãœããããªãŒããŒã©ã€ããå§ãããããããã¯NSubsituteã®æ¬¡ã®ã¡ãžã£ãŒããŒãžã§ã³ã§è§£æ±ºãããããšã§ãã ãã®çµæãxUnitã¯ããããã£ã«ã¢ã¯ã»ã¹ããªããªããŸããã
æªããã¥ãŒã¹ã¯ãNSubsitutev4ããŸã ãªãªãŒã¹ãããŠããªãããšã§ãã
ç§ã¯ããªãã«ã©ã¡ãããææ¡ããããšãã§ããŸãïŒ
master
ãœãŒã¹ã³ãŒãã䜿çšããããŒã«ã«ãã«ããäœæããŠãNuGetããã±ãŒãžã®ä»£ããã«ç¬èªã®NSubsitute.dll
䜿çšããŸãã v4ããªãªãŒã¹ãããããNuGetããã±ãŒãžã«åãæ¿ããããšãã§ããŸãããäžäŸ¿ããããããŠç³ãèš³ãããŸããããæ®å¿µãªããAutoFixtureåŽã§ã¯ãã®åé¡ã解決ããããšã¯ã§ããŸããã
ããããã¹ãããŸããã æåŸã«ãReceivedCallsãã¢ãµãŒããããã¹ããæ»ã£ãŠãåã³æåããçµæãåŸãããŸããã
ããã§ã倱æããã®ã¯ãReceivedïŒ1ïŒ.Speed Danielã®ãããªReceivedïŒxïŒã§ã®ã¢ãµãŒãã§ãã
åžœåã®çã/解決çããããŸããïŒ
åããããžã§ã¯ãã«åãçµãã§ããŸããïŒ :)ãããããªããã©ã®ããã«åé¡ãä¿®æ£ããããæ確ã«ã§ããŸããïŒ
äžã§ææ¡ããããªãã·ã§ã³ã¯ãäž¡æ¹ã®åé¡ã«åœ¹ç«ã€ã¯ãã§ãã ããã§ãªãå Žåã¯ãã·ããªãªãæ確ã«ããŸãã
å®éã«ã¯åããããžã§ã¯ãã§ã¯ãªããåãäŒç€Ÿã§ãã
ç§ãã¡ã¯é·ãéxunit1.9 + nsubstitute 2/3ã䜿çšããŠããŠãæçµçã«ããã管çããŠå
éšã¢ã»ã³ããªãååŸããŸããïŒnugetããã±ãŒãžãªã®ã§ã1ã€ã®åç
§ã®å€ãããŒãžã§ã³ã«æ»ãç°¡åãªæ¹æ³ã¯æã£ãã»ã©ç°¡åã§ã¯ãããŸããxunit2ãšäºææ§ãããããšã ãããŠä»ãç§ãã¡ã¯ãããã®2ã€ã®åé¡ãæ±ããŠããŸãã
ç§ãã¡ã¯ãã§ã«ããã€ãã®ããšãè©ŠããŸããããæçµçã«ã¯èªåãã£ã¯ã¹ãã£ãšé¢ä¿ãããã«éããªããšèããŸãã-åçµãããå±æ§ãšããŒãã³ãŒãããããã¹ãå®è¡ã«ãŠã³ãã®ããã«-ãŸãã¯ãã®ãããªãã®ã
ãããšã«ããã®äºä»¶ãéããåŸã圌ã¯ç§ã«ãããžã®ãªã³ã¯ãæçš¿ããŸããã
äžã§èª¬æããããã«ãnuget3.1ãªãã¡ã¬ã³ã¹ãæ°ããã³ã³ãã€ã«ãããnsubstituteãããžã§ã¯ãã®ãã®ã«çœ®ãæããŸããã ãã®åŸãReceicedïŒxïŒããŸã ééã£ãåŒã³åºãæ°ãè©äŸ¡ããŠããããã178åã§ã¯ãªã118åã®ãã¹ãã倱æããŸããã
ç§ã®ãããžã§ã¯ãã¯çŸåšãxunit2ãåãã.net 4.5.2ã«åºã¥ããŠãããnsubstituteã®çŸåšã®ãªããžããªããŒãžã§ã³ãšautofixture4.2ãåç
§ãããŠããŸãã ãã¹ãŠã®ãã¹ããåã2ã€ã®çç±ã§å€±æããŠããŸãããŸããåäœãã¹ãã§å€±æããåä¿¡ã³ãŒã«ããŸã ããã€ããããŸãã
ç§ãåã³ãªãã£ã¹ã«æ»ã£ããšãïŒã€ãŒã¹ã¿ãŒã®ããã«ïŒãç§ã¯ãããããäžåºŠæ·±ã調ã¹ãå¿
èŠããããšæããŸãã
ãã®éã @ dklingerãã·ããªãªã説æã§ãããããããŸããã
@dklinger @evilbaschdi確èªããæ©äŒããã£ããããã©ããŒã¢ããããŠãã ãããããããé©çšããåŸã§ãããªãåé¡ãçºçããã®ãã¯éåžžã«èå³æ·±ããã®ã§ãã
åé¡ãå床éããŠããŸã 調æ»ãé²è¡äžã§ããããšã瀺ããŸãã
ããŠãããæ°æéãã¹ãããŸããã æåã«ïŒããªãã®è¿äºãããªãã®èª¬æãšææ¡ã«æè¬ããŸã-ããã¯å€§ãã«åœ¹ç«ã¡ãŸããã
NSubstituteã®v4ããã¹ãããŸããã äžèšã®ãµã³ãã«ã³ãŒãã§ã¯æ©èœããŸãããå®éã®ãããžã§ã¯ãã§ã¯åé¡ãå®å
šã«è§£æ±ºããããã§ã¯ãããŸããã åé¡ã¯ãééã£ãReceivedCallsã®åé¡ã解決ããããšã§ã-ããããã£ã§ã¯ãªããã¡ãœãããžã®SUT-Callsã«å¯ŸããŠã®ã¿ã«ãŠã³ããããŸãã
çŸåšæ©èœããŠããã³ãŒãã®äŸïŒ
[Theory, AutoNSubstituteData]
public void DoItNow_UsingAutoNSubstitute(
[Frozen] IRunSpeed runSpeed,
GetToDaChoppa sut)
{
// Arrange
runSpeed.Speed.Returns(49);
//Act
sut.DoItNow();
//Assert
var tmp = runSpeed.Received(1).Speed;
Assert.Equal(1, runSpeed.ReceivedCalls().Count());
}
ããããã¡ãœãããGetToDaChoppa.DoItNowïŒïŒ;ããå€æŽãããšã ããããã£ãGetToDaChoppa.DoItNowãã«ãªãã«ã¯ãReceivedCallsCountãåã³+1ã«ãªããŸãã
[Theory, AutoNSubstituteData]
public void DoItNow_UsingAutoNSubstitute(
[Frozen] IRunSpeed runSpeed,
GetToDaChoppa sut)
{
// Arrange
runSpeed.Speed.Returns(49);
//Act
var x = sut.DoItNow;
//Assert
var tmp = runSpeed.Received(1).Speed;
Assert.Equal(1, runSpeed.ReceivedCalls().Count());
}
äœæ¥ã¡ãœããã®å®è£
ã®ããã«ãããååŸããã®ã§ããããxUnitã®åœåã«é¢ä¿ããŠãããšæããŸãã
ãããŠãããã¯æ©èœããªãããããã£ã®å®è£
ã®ããã®ãã®ã§ãïŒ
xUnitãSUTããããã£ãåŒã³åºããŠå€ãååŸãããã¹ãåã«äœ¿çšããŠããããã§ãããSUTã¡ãœããã§ã¯ãããè¡ã£ãŠããŸããã ç§ãæåã«èããã®ã¯ãç¡å¹ã ã£ãã¡ãœãããGetToDaChoppaïŒïŒãã®æ»ãå€ã«é¢ä¿ããŠãããšããããšã§ããã ãã ãããpublic int GetToDaChoppaïŒïŒãã«å€æŽããåŸã§ããxUnitã¯ãã¹ãåã®æ»ãå€ãååŸããããã«ãããåŒã³åºããŠããŸããã ããããã£ã®äœ¿çšã®ã¿ãåé¡ã«ãªããŸãã
ä»ã®ãšããç§ã¯åã³ç«ã¡åŸçããŠããŸãã ãããAutoFixtureã®åé¡ã§ã¯ãªãããšã«å®å šã«åæããŸãã ããããããªãã®æèŠã§ã¯ãç§ãã¡ããããã¹ãŠã®ãã±ãããããç¥ã£ãŠãããšããããããªãã®ææ¡ã¯äœã§ããããïŒ
@dklingerãã©ããŒã¢ããããŠãããŠããããšãïŒ ããã§ã倱æããæåŸã®ã·ããªãªã®ã³ãŒãã®MCVEãå ±æããŠ
ãã®åŸããªããããèµ·ããã®ãããããŠãããåé¿ããæ¹æ³ã調æ»ããããšæããŸãã
ããããšãã
ããã確ãã«ã ããã«ãããŸãïŒ
ãã¹ã察象ã·ã¹ãã ïŒ
public interface IRunSpeed
{
int Speed { get; }
void Dude();
int Dude2();
}
public class GetToDaChoppa
{
private readonly IRunSpeed _runSpeed;
public GetToDaChoppa(IRunSpeed runSpeed)
{
_runSpeed = runSpeed ?? throw new ArgumentNullException(nameof(runSpeed));
}
public int DoItNow
{
get
{
var runningSpeed = _runSpeed.Speed;
return 0;
}
}
}
ãã¹ãã±ãŒã¹ïŒ
[Theory, AutoNSubstituteData]
public void DoItNowAsProperty_UsingAutoNSubstitute(
[Frozen] IRunSpeed runSpeed,
GetToDaChoppa sut)
{
// Arrange
runSpeed.Speed.Returns(49);
//Act
var x = sut.DoItNow;
//Assert
var tmp = runSpeed.Received(1).Speed;
Assert.Equal(1, runSpeed.ReceivedCalls().Count());
}
çŸåšã httpsïŒ//github.com/xunit/xunit/issues/1386ããã³https://github.com/AutoFixture/AutoFixture/issues/805ã§ã®è°è«ã«è¿œãã€ãããã«ããŠã
ãŸããDisplayNameããããã£ããªãŒããŒã©ã€ãããç¬èªã®TheoryAttributeãäœæããããšããŸããããxUnitãäœããã®æ¹æ³ã§èªåçæãããååãå
éšã§äœ¿çšããŠãããããããã圹ã«ç«ã¡ãŸããã ããããããã¯åãªãåèã§ãããäžèšã®ãã¢ã³ãŒããšã¯ãŸã£ããé¢ä¿ãããŸããã
public sealed class MyTheoryAttribute : TheoryAttribute
{
public MyTheoryAttribute([CallerMemberName] string memberName = null)
{
DisplayName = "MyTestCase";
}
}
ããã«ã¡ã¯ãç§ã ã:)
å®éãxUnit2ã¯ãè€ååã®test-method-parametersã®ãã¹ãŠã®ããããã£ãšãã£ãŒã«ããåŒã³åºããŠããŸãã ã³ãŒãè¡ã¯æ¬¡ã®ãšããã§ãïŒ https ïŒ
ãååããããšãããããŸããã xUnit-Repoã§åé¡ãåéããŸãããããã§ããã£ã¹ã«ãã·ã§ã³ãç¶ããå¿ èŠããããŸãïŒ https ïŒ
@dklinger詳现ãªã·ããªãªãããããšãã ããã¯ç¢ºãã«ããªãããªãããŒã§ãããã©ãããããããããåé¿ããã®ã¯é£ããã§ãã AutoFixtureãšNSubsituteã®èŠ³ç¹ããã¯ãã³ãŒããxUnitã®å¥¥æ·±ãã§åŒã³åºããããããã¹ãæ¬äœã®ã©ããã§åŒã³åºããããã«éãã¯ãããŸããã
éåžžãåé¿çãšããŠãNSubstituteã®æ確ãªæ©èœã䜿çšã§ããŸãã
runSpeed.ClearReceivedCalls();
ãã®ã³ãŒãã¯ãæ£ç¢ºãªåŒã³åºãæ°ã確èªããåãã¹ãã®ããããŒã°ã§å®è¡ããå¿ èŠããããŸãã ããã€ãã®ãã¹ããããã°åé¡ãªãåäœããŸãããæããã«ãäœåãã®ãã¹ãã圱é¿ãåããå Žåã¯ãããŸã圹ã«ç«ã¡ãŸããð
NSubsitute + xUnit2 + AutoFixtureã®çµ±åãããŸãæ©èœããããã®çš®ã®åé¡ã«æ©ãŸãããŠããã®ã¯æ®å¿µã§ãã AutoFixture補åã¯ãæªå€¢ã§ã¯ãªããç掻ãç°¡çŽ åããããã«èšèšãããŠããŸãðxUnitã®ã¹ã¿ãããããããžã§ã¯ãå šäœã®åé¡ããã°ãã解決ããæ¹æ³ãã¢ããã€ã¹ããŠãããããšãé¡ã£ãŠããŸãã
ç¶æ³ãæ¹åããããã«ç§ãã¡ã®åŽããäœãã§ãããšæãããå Žåã¯ãç¥ãããã ããã