여러 가지 방법이 있습니다.
[Fact]
public void ImperativeTest()
{
var fixture = new Fixture();
var expected = fixture.CreateMany<SyncItem>(3).OrderBy(si => si.Key);
var unorderedItems = expected.Skip(1).Concat(expected.Take(1)).ToArray();
fixture.Inject(unorderedItems);
var sut = fixture.Create<SyncItemList>();
Assert.Equal(expected, sut);
}
이 the default number of many items is 3 동안, 나는 그것이이 테스트 케이스에 명시 적으로 그것을 밖으로 전화를하는 것이 좋습니다 생각 :
명령형 버전
다음은 OP에서 제공하는 것보다 더 간단 필수적 버전입니다. 여기에서 사용 된 스크램블링 알고리즘은 이후에의 순서로 세 개의 (구별되는) 요소의 순서를 지정하고, 첫 번째 요소를 뒤쪽으로 이동하면 이이되어야 정렬되지 않은 목록이됩니다.
그러나이 접근법의 문제점은 fixture
의 변이에 의존하기 때문에보다 선언적인 방식으로 리팩터링하기가 어렵습니다.(
public class UnorderedSyncItems : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new UnorderedSyncItemsGenerator());
}
private class UnorderedSyncItemsGenerator : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
var t = request as Type;
if (t == null ||
t != typeof(SyncItem[]))
return new NoSpecimen(request);
var items = ((IEnumerable)context
.Resolve(new FiniteSequenceRequest(typeof(SyncItem), 3)))
.Cast<SyncItem>();
return items.Skip(1).Concat(items.Take(1)).ToArray();
}
}
}
new FiniteSequenceRequest(typeof(SyncItem), 3))
단순히 약한 타입입니다 해결 : 더 선언적 버전으로 리팩토링하기위한 노력의 일환으로
사용자 정의 버전
는 먼저 a Customization에서 스크램블링 알고리즘을 캡슐화 할 수 있습니다 비 - 일반) SyncItem
인스턴스의 유한 시퀀스를 만드는 방법; 그것은 무엇이 CreateMany<SyncItem>(3)
뒤에 무엇입니까.
[Fact]
public void ImperativeTestWithCustomization()
{
var fixture = new Fixture().Customize(new UnorderedSyncItems());
var expected = fixture.Freeze<SyncItem[]>().OrderBy(si => si.Key);
var sut = fixture.Create<SyncItemList>();
Assert.Equal(expected, sut);
}
을 주목 Freeze 방법의 사용 :
는
이에 테스트를 리팩토링 할 수 있습니다. UnorderedSyncItems
사용자 지정은 SyncItem[]
인스턴스가 생성되는 방식 만 변경하기 때문에 필요합니다. 그렇게 할 요청을받을 때마다 여전히 새로운 배열을 생성합니다. Freeze
은 fixture
이 sut
인스턴스를 생성 할 때마다 동일한 배열이 매번 다시 사용되도록합니다.
은 협약 기반 테스트 위의 테스트가 [UnorderedConventions]
속성의 도입으로, 선언, 규칙 기반의 테스트를 리팩토링 할 수
는 :
public class UnorderedConventionsAttribute : AutoDataAttribute
{
public UnorderedConventionsAttribute()
: base(new Fixture().Customize(new UnorderedSyncItems()))
{
}
}
이것은 단순히 선언적 접착제입니다 UnorderedSyncItems
사용자 지정을 적용합니다. 시험은 지금된다 :
[Theory, UnorderedConventions]
public void ConventionBasedTest(
[Frozen]SyncItem[] unorderedItems,
SyncItemList sut)
{
var expected = unorderedItems.OrderBy(si => si.Key);
Assert.Equal(expected, sut);
}
주목하라 [UnorderedSyncItems]
및 [Frozen]
속성의 사용.
이 테스트는 매우 간결하지만 나중에 수행 한 테스트가 아닐 수 있습니다. 문제는 행동의 변경이 이제 [UnorderedSyncItems]
속성에 숨겨져있어 상황이 암묵적이라는 것입니다. 나는 동일한 사용자 정의을 전체 테스트 스위트에 대한 규칙 세트로 사용하는 것을 선호하므로이 레벨에서 테스트 케이스 변형을 소개하고 싶지 않습니다. 그러나 규범에 따라 SyncItem[]
인스턴스가 이어야하며 항상이어야합니다. 그러면이 규칙이 양호합니다.
그러나 일부 경우에만 테스트 케이스에 정렬되지 않은 배열을 사용하려는 경우 [AutoData]
속성을 사용하는 것이 가장 적합한 방법이 아닙니다.
선언적 테스트 케이스
당신은 단순히 그냥 [Frozen]
속성과 같은 매개 변수 레벨 속성을 적용 할 수 있다면 그것은 좋은 것 - 아마도 [Unordered][Frozen]
처럼 그들을 결합. 그러나이 방법은 효과가 없습니다.
주문이 인 이전 예에서 유의하십시오. 동결되기 전에 UnorderedSyncItems
을 적용해야합니다. 그렇지 않으면 동결되는 배열의 정렬이 보장되지 않을 수 있기 때문입니다.
[Unordered][Frozen]
매개 변수 수준 특성의 문제점은 컴파일하는 동안 .NET Framework에서 AutoFixture xUnit.net 글루 라이브러리가 특성을 읽고 적용 할 때 특성 순서를 보장하지 않는다는 것입니다.
대신에, 당신은 다음과 같이 적용 할 하나의 속성을 정의 할 수 있습니다
public class UnorderedFrozenAttribute : CustomizeAttribute
{
public override ICustomization GetCustomization(ParameterInfo parameter)
{
return new CompositeCustomization(
new UnorderedSyncItems(),
new FreezingCustomization(parameter.ParameterType));
}
}
을 (FreezingCustomization
이 [Frozen]
속성의 기본 구현을 제공합니다.)
을이이 테스트를 작성 할 수 있습니다 :
를
[Theory, AutoData]
public void DeclarativeTest(
[UnorderedFrozen]SyncItem[] unorderedItems,
SyncItemList sut)
{
var expected = unorderedItems.OrderBy(si => si.Key);
Assert.Equal(expected, sut);
}
이 선언 테스트에서는 Customice 없이도 기본 [AutoData]
특성을 사용합니다 왜냐하면 스크램블은 매개 변수 수준에서 [UnorderedFrozen]
속성에 적용되기 때문입니다.
이렇게하면 [AutoData]
유도 속성에 캡슐화 된 (다른) 테스트 스위트 전체 규칙을 사용할 수 있으며 여전히 옵트 인 메커니즘으로 [UnorderedFrozen]
을 사용합니다.
'SyncItemList'는 어떻게 보이나요? –
당신은 정말 멋지 겠지만, 속성과 UnOrdered 요청 유형이 있다면, 유한 계열과 비슷합니다. 3 개 이상의 고유 항목 만 있으면되고 순서가 잘못된 순서를 보장 할 수 있습니다. – cocogorilla
어떤 버전의 AutoFixture를 사용하고 있습니까? AutoFixture 3에서 [Numbers are random] (https://github.com/AutoFixture/AutoFixture/wiki/AutoFixture-3.0-Release-Notes#numbers-are-random)을 입력하십시오. –