'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'๊ฐ ์ ๋๋ก ์๋ํฉ๋๋ค. ๊ทธ๋ฌ๋ ๋ ๋ฒ์งธ ํ
์คํธ 'DoItNow_UsingAutoNSubstitute'๋ 'ios.Received(1).Speed;'์ ๋ํด 2๋ฅผ ๋ฐํํฉ๋๋ค.
๋ํ 'runSpeed.ReceivedCalls();'์ ๋ํด 2๋ฅผ ๋ฐํํฉ๋๋ค.
์ด ๋๋ฌธ์ ํ์ฌ ์๋ฃจ์
๋น ํ
์คํธ ์คํจ๊ฐ 1000๊ฐ ์ด์์ด๋ฏ๋ก ํ์ฌ ์๋ฃจ์
์ v4๋ก ์
๊ทธ๋ ์ด๋ํ ์ ์์ต๋๋ค. ๋ฌธ์ ๊ฐ ๋ฌด์์ธ์ง ๋๋ ์์ ์ฌํญ์ ์ฐพ์ ์ ์๋ ์์น์ ๋ํ ์ง์นจ์ด ์์ต๋๊น?
๋ฌธ์ ๋ฅผ ํด๊ฒฐํด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. ์ฌ์ค, ์ด ๋ฌธ์ ๋ AutoFixture์ ์๋ฌด ๊ด๋ จ์ด ์์ง๋ง ์ฐ๋ฆฌ๋ ์ํฅ์ ๋ฐ์ต๋๋ค ๐
์ด ๋ฌธ์ ๋ ๋๋ถ๋ถ xUnit์ ์ํด ๋ฐ์ํ๋ฉฐ ๋ค์๊ณผ ๊ฐ์ด ํ
์คํธ๋ฅผ ๋ค์ ์์ฑํ๋ฉด ํต๊ณผํฉ๋๋ค.
```c#
[์ด๋ก , AutoNSubstituteData]
๊ณต๊ฐ ๋ฌดํจ DoItNow_UsingAutoNSubstitute_CreateManually(IFixture ๊ณ ์ ์ฅ์น)
{
// ๋ง๋ จํ๋ค
var runSpeed โโ= fixture.Freeze
var sut = ๊ณ ์ ๋ฌผ.๋ง๋ค๊ธฐ
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์ ๋ ์ด์ ์์ฑ์ ๊ฑด๋๋ฆฌ์ง ์์ต๋๋ค.
๋์ ์์์ NSubsitute v4๊ฐ ์์ง ์ถ์๋์ง ์์๋ค๋ ๊ฒ์ ๋๋ค.
๋ค์ ์ค ํ๋๋ฅผ ์ ์ํ ์ ์์ต๋๋ค.
master
์์ค ์ฝ๋๋ฅผ ์ฌ์ฉํ๊ณ ๋ก์ปฌ ๋น๋๋ฅผ ๋ง๋ค๊ณ NuGet ํจํค์ง ๋์ ์์ฒด NSubsitute.dll
์ฌ์ฉํฉ๋๋ค. v4๊ฐ ๋ฆด๋ฆฌ์ค๋ ํ NuGet ํจํค์ง๋ก ์ ํํ ์ ์์ต๋๋ค.๋ถํธ์ ๋๋ ค ์ฃ์กํฉ๋๋ค. ํ์ง๋ง ์ํ๊น๊ฒ๋ AutoFixture ์ธก์์๋ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์๋ฌด ๊ฒ๋ ํ ์ ์์ต๋๋ค.
๋ฐฉ๊ธ ์ด๊ฒ์ ํ
์คํธํ์ต๋๋ค. ๋ง์นจ๋ด ReceivedCalls๋ฅผ ์ฃผ์ฅํ๋ ํ
์คํธ๊ฐ ๋ค์ ์ฑ๊ณต์ ์ธ ๊ฒฐ๊ณผ๋ฅผ ์ป์์ต๋๋ค.
์ฌ์ ํ ์คํจํ๋ ๊ฒ์ ์์์ ์ธ๊ธํ Received(1).Speed โโDaniel๊ณผ ๊ฐ์ Received(x)์ ๋ํ ์ฃผ์ฅ์
๋๋ค.
๋ชจ์์ ๋ํ ๋ต๋ณ / ์๋ฃจ์ ๋ ์์ต๋๊น?
๊ฐ์ ํ๋ก์ ํธ๋ฅผ ์งํ ์ค์ด์ ๊ฐ์? :) ๊ทธ๋ ๋ค๋ฉด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ๋ฐฉ๋ฒ์ ๋ช ํํ ํด์ฃผ์ค ์ ์์ต๋๊น?
์์์ ์ ์ํ ์ต์ ์ ๋ ๊ฐ์ง ๋ฌธ์ ์ ๋ชจ๋ ๋์์ด ๋ฉ๋๋ค. ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ - ์๋๋ฆฌ์ค๋ฅผ ๋ช ํํ ํฉ๋๋ค.
์ค์ ๋ก ๊ฐ์ ํ๋ก์ ํธ๊ฐ ์๋๋ผ ๊ฐ์ ํ์ฌ์์.
์ฐ๋ฆฌ๋ xunit 1.9 + nsubstitute 2 / 3์ ์ค๋ซ๋์ ์ฌ์ฉํด์๊ณ ๋ง์นจ๋ด ๋ด๋ถ ์ด์
๋ธ๋ฆฌ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํด ๊ด๋ฆฌํ์ต๋๋ค(nuget ํจํค์ง์ด๋ฏ๋ก ํ๋์ ์ฐธ์กฐ๋ง ์๋ ์ด์ ๋ฒ์ ์ผ๋ก ๋์๊ฐ๋ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ ์๋ฆฌ๋งํผ ์ฝ์ง ์์ต๋๋ค ๋ ) xunit2์ ํธํ๋ฉ๋๋ค. ์ด์ ์ด ๋ ๊ฐ์ง ๋ฌธ์ ๊ฐ ์์ต๋๋ค.
์ฐ๋ฆฌ๋ ์ด๋ฏธ ๋ช ๊ฐ์ง๋ฅผ ์๋ํ๊ณ ๋ง์นจ๋ด ๊ทธ๊ฒ์ด ์๋ ๊ณ ์ ๊ณผ ๊ด๋ จ์ด ์์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ์ต๋๋ค. ์๋ํ๋ฉด frozen-์์ฑ๊ณผ ํ๋ ์ฝ๋ฉ๋ ํ
์คํธ ์คํ ํ์ ๋๋ฌธ์
๋๋ค.
๋ค๋์์ด ์ด ์ผ์ด์ค๋ฅผ ์ฐ ํ ๊ทธ๋ ๋์๊ฒ ๊ทธ๊ฒ์ ๋ํ ๋งํฌ๋ฅผ ๊ฒ์ํ์ต๋๋ค.
์์์ ์ค๋ช ํ ๊ฒ์ฒ๋ผ nuget 3.1 ์ฐธ์กฐ๋ฅผ ์๋ก ์ปดํ์ผ๋ nsubstitute ํ๋ก์ ํธ์ ์ฐธ์กฐ๋ก ๋์ฒดํ์ต๋๋ค. ๊ทธ ํ Receiced(x)๊ฐ ์ฌ์ ํ ์๋ชป๋ ํธ์ถ ํ์๋ฅผ ํ๊ฐํ๊ณ ์๊ธฐ ๋๋ฌธ์ 178๊ฐ์ ์คํจํ ํ ์คํธ ๋์ 118๊ฐ์ ํ ์คํธ๊ฐ ์คํจํ์ต๋๋ค.
๋ด ํ๋ก์ ํธ๋ ํ์ฌ xunit2, nsubstitute์ ํ์ฌ repo ๋ฒ์ ๋ฐ autofixture 4.2๊ฐ ์ฐธ์กฐ๋ .net 4.5.2๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํฉ๋๋ค. ๋ชจ๋ ํ
์คํธ๊ฐ ๋์ผํ ๋ ๊ฐ์ง ์ด์ ๋ก ์คํจํ๊ณ ์์ต๋๋ค. ๋ํ ๋จ์ ํ
์คํธ์์ ์ฌ์ ํ ์คํจํ ์ผ๋ถ ์์ ํธ์ถ์ด ์์ต๋๋ค.
๋๋ ๋ค์ ์ฌ๋ฌด์ค๋ก ๋์๊ฐ ๋(๋ถํ์ ์ ์ํด) ๋ ๊น์ด ๋ค์ฌ๋ค๋ด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
ํํธ @dklinger ๋ ์๋๋ฆฌ์ค๋ฅผ ์ค๋ช
ํ ์ ์์ต๋๋ค.
@dklinger @evilbaschdi ํ์ธ ํ ํ์ ์กฐ์น๋ฅผ ์ทจํด ์ฃผ์ญ์์ค. ํจ์น๋ฅผ ์ ์ฉํ ํ์๋ ๋ฌธ์ ๊ฐ ๊ณ์ ๋ํ๋๋ ์ด์ ๋ ๋งค์ฐ ํฅ๋ฏธ๋กญ์ต๋๋ค.
์์ง ์กฐ์ฌ๊ฐ ์งํ ์ค์์ ๋ํ๋ด๊ธฐ ์ํด ๋ฌธ์ ๋ฅผ ๋ค์ ์ฝ๋๋ค.
์ข์์, ๊ทธ๋์ ์ง๋ ๋ช ์๊ฐ ๋์ ํ
์คํธํ์ต๋๋ค. ์ฒซ์งธ: ๊ทํ์ ๋ต๋ณ, ์ค๋ช
๋ฐ ์ ์์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ๋ง์ ๋์์ด ๋์์ต๋๋ค.
NSubstitute์ v4๋ฅผ ํ
์คํธํ์ต๋๋ค. ์์ ์์ ์ฝ๋์์๋ ์๋ํ์ง๋ง ์ค์ ํ๋ก์ ํธ์์ ๋ฌธ์ ๋ฅผ ์์ ํ ํด๊ฒฐํ์ง๋ ๋ชปํฉ๋๋ค. ๋ฌธ์ ๋ ์์ฑ์ด ์๋ ๋ฉ์๋์ ๋ํ SUT ํธ์ถ์ ๋ํด์๋ง ์๋ชป๋ 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.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 ์์ฑ์ ์ฌ์ ์ํ๋ ๋๋ง์ ์ด๋ก ์์ฑ์ ๋ง๋ค๋ ค๊ณ ์๋ํ์ง๋ง xUnit์ด ์ฌ์ ํ ๋ด๋ถ์ ์ผ๋ก ์๋ ์์ฑ๋ ์ด๋ฆ์ ์ฌ์ฉํ๊ณ ์๊ธฐ ๋๋ฌธ์ ๋์์ด ๋์ง ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด๋ ์ฐธ๊ณ ์ฉ์ผ ๋ฟ์ด๋ฉฐ ์์ ๋ฐ๋ชจ ์ฝ๋์ ์ ํ ๊ด๋ จ์ด ์์ต๋๋ค.
public sealed class MyTheoryAttribute : TheoryAttribute
{
public MyTheoryAttribute([CallerMemberName] string memberName = null)
{
DisplayName = "MyTestCase";
}
}
์๋
, ๋ ๋์ผ :)
๋ณตํฉ ์ ํ์ธ ํ
์คํธ ๋ฐฉ๋ฒ ๋งค๊ฐ๋ณ์์ ๋ชจ๋ ์์ฑ ๋ฐ ํ๋๋ฅผ ํธ์ถํ๋ ๊ฒ์ ์ค์ ๋ก xUnit2์
๋๋ค. ์ฝ๋ ์ค์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. https://github.com/xunit/assert.xunit/blob/2b70a9b0c5bb291f98472ec24cec437acf8d65c8/Sdk/ArgumentFormatter.cs#L156
์ง์ํด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. ํ ๋ก ์ด ๊ณ์๋์ด์ผ ํ๋ xUnit-Repo์์ ๋ฌธ์ ๋ฅผ ๋ค์ ์ด์์ต๋๋ค. https://github.com/xunit/xunit/issues/1682
@dklinger ์์ธํ ์๋๋ฆฌ์ค์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ๊ทธ๊ฒ์ ์ค์ ๋ก ์๋นํ ๊น๋ค๋กญ๊ณ ์ด๋ป๊ฒ๋ ํด๊ฒฐํ๊ธฐ ์ด๋ ต์ต๋๋ค. AutoFixture์ NSubsitute ๊ด์ ์์ ๋ณด๋ฉด ์ฝ๋๊ฐ xUnit ๋ด๋ถ ๊น์ํ ๊ณณ์์ ํธ์ถ๋๋ ํ ์คํธ ๋ณธ๋ฌธ์์ ํธ์ถ๋๋ ์ฐจ์ด๊ฐ ์์ต๋๋ค.
์ผ๋ฐ์ ์ผ๋ก ํด๊ฒฐ ๋ฐฉ๋ฒ์ผ๋ก NSubstitute์ ๋ช ํํ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
runSpeed.ClearReceivedCalls();
์ด ์ฝ๋๋ ์ ํํ ํธ์ถ ์๋ฅผ ํ์ธํ๋ ๊ฐ ํ ์คํธ์ ํ๋กค๋ก๊ทธ์์ ์คํํด์ผ ํฉ๋๋ค. ๋ช ๊ฐ์ง ํ ์คํธ๊ฐ ์์ผ๋ฉด ์ ์๋ํ์ง๋ง ๋ถ๋ช ํ ์์ฒ ๊ฐ์ ํ ์คํธ๊ฐ ์ํฅ์ ๋ฐ์ผ๋ฉด๋ณ๋ก ๋์์ด๋์ง ์์ต๋๋ค ๐
NSubsitute + xUnit2 + AutoFixture ํตํฉ์ด ์ ๋๋ก ์๋ํ์ง ์๊ณ ์ด๋ฌํ ์ข ๋ฅ์ ๋ฌธ์ ๋ก ๊ณ ํต๋ฐ๋ ๊ฒ์ ์ ๊ฐ์ ๋๋ค. AutoFixture ์ ํ์ ์ ๋ชฝ์ ๊พธ๊ธฐ๋ณด๋ค๋ ์ถ์ ๋จ์ํํ๋๋ก ์ค๊ณ๋์์ต๋๋ค ๐ xUnit์ ์ง์๋ค์ด ์ ์ฒด ํ๋ก์ ํธ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋น ๋ฅธ ๋ฐฉ๋ฒ์ ์กฐ์ธํด์ฃผ๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
์ํฉ์ ๊ฐ์ ํ๊ธฐ ์ํด ์ฐ๋ฆฌ ์ธก์์ ๋ญ๊ฐ๋ฅผ ํ ์ ์๋ค๊ณ ์๊ฐ๋๋ฉด ์๋ ค์ฃผ์ญ์์ค.