2014-08-27 7 views
2

NUnit은 실제 값이 주어진 열거 가능 또는 배열의 요소인지, 즉 여러 기대 값 중 하나와 같은지 여부를 찾기 위해 제약 조건을 제공합니까? 가치? 같은 뭔가 : 지적하는 것입니다값이 예상 값 모음 중 하나와 같음을 나타냅니다.

Assert.That(actual, Is.EqualToAnyOf(new[] { 1, 2, 3 })) 

은의 실제는 하나의 값입니다. 값이 1, 2 또는 3 일 것으로 예상됩니다. 주장

Assert.That(actual, Contains.Element(expected)) 

검사 논리적으로 동일하지만, 반대의 의도는 다음과 같습니다 여기에 우리가 실제 값의 컬렉션을 가지고 하나 개의 값이 될 것으로 기대합니다.

또한, 나는이를 찾았지만 그들은 모두 맞지 않는 :

Assert.That(actual, Is.EqualTo(expected)) // only allows one value 
Assert.That(actual, Is.InRange(start, end)) // only works for consecutive numbers 
Assert.That(actual, Is.SubsetOf(expected)) // only works if actual is an enumerable 
Assert.That(expected.Contains(actual)) // meaningless "expected: true but was: false" message 

답변

0

나는이 자신의 제약 조건을 만드는 것입니다 달성하기 위해 볼 수있는 유일한 방법. 그래도 꽤 간단합니다.

제약 클래스 자체는 :

public class OneOfValuesConstraint : EqualConstraint 
{ 
    readonly ICollection expected; 
    NUnitEqualityComparer comparer = new NUnitEqualityComparer(); 

    public OneOfValuesConstraint(ICollection expected) 
     : base(expected) 
    { 
     this.expected = expected; 
    } 

    public override bool Matches(object actual) 
    { 
     // set the base class value so it appears in the error message 
     this.actual = actual; 
     Tolerance tolerance = Tolerance.Empty; 

     // Loop through the expected values and return true on first match 
     foreach (object value in expected) 
      if (comparer.AreEqual(value, actual, ref tolerance)) 
       return true; 

     // No matches, return false 
     return false; 
    } 

    // Overridden for a cleaner error message (contributed by @chiccodoro) 
    public override void WriteMessageTo(MessageWriter writer) 
    { 
     writer.DisplayDifferences(this); 
    } 

    public override void WriteDescriptionTo(MessageWriter writer) 
    { 
     writer.Write("either of "); 
     writer.WriteExpectedValue(this.expected); 
    } 
} 

그리고 유창, 그것을 포장하는 정적 메서드를 만들 수 있도록 (@chicodorro로 기여) :

public static class IsEqual 
{ 
    public static OneOfValuesConstraint ToAny(ICollection expected) 
    { 
     return new OneOfValuesConstraint(expected); 
    } 
}  

이 그 다음을 사용 :

int[] expectedValues = new[] { 0, 1, 2 }; 
Assert.That(6, IsEqual.ToAny(expectedValues)); 

메시지와 함께 실패합니다.

>

2 0, 1 < 중 하나를하지만했다 :

는 예상 6

+0

+1 답변이 왜 내려 갔는지 알 수 없습니다. 나는 그것이 내가 원한 것에 가장 가깝다고 생각한다. 나는이 주장이 상자에서 제공되기를 바랄 뿐이었다. – chiccodoro

+0

나는 다음을 사용하여 "숙제"(1)를 해결했다 : writer.WritePredicate ("of either"); writer.WriteExpectedValue (this.expected);'와 (2) IsEqual.ToAny (expected) 메소드를 제공한다. 그러나 메시지를 적용하려면 기본 클래스를 '제약 조건'으로 변경해야했습니다. 왜 그런지 물어 보지 마세요 ... 메시지가 지금 읽습니다. '예상 됨 : < 0, 1, 2 > 중 하나 : 6' – chiccodoro

+0

@chiccodoro, 감사합니다. –

4

CollectionAssert 내가 뭔가를 내려다 있지 않다 경우 당신이 필요로해야한다.

[Test] 
public void CollectionContains() 
{ 
    var expected = new List<int> { 0, 1, 2, 3, 5 }; 
    var actual = 5; 

    CollectionAssert.Contains(expected, actual); 
    Assert.That(expected, Contains.Item(actual)); 
} 

위 주장은 기본적으로 같은 주장해야하며, 상호 교환 사용할 수 :

CollectionAssert.Contains(IEnumerable expected, object actual); 

그러나, 같은 목표를 달성하기 위해 여러 가지 방법이있을 것 같다만큼 간단합니다.

편집 : 질문은 논리적으로 같은 일을 테스트에도 불구하고 Assert.That(expected, Contains.Item(actual));이 유효하지 않음을 알리는 수정되었습니다.

+0

불행히도 내 질문의 제목을 변경하면 답변이 될 수 있지만 그렇지 않습니다. 제 제안의 일부가했던 것처럼 제안서가 예상대로 혼합됩니다. 어설 션이 실패 할 경우 나타나는 오류 메시지를보십시오. – chiccodoro

+0

funnily 당신이 쓴 것처럼 당신이 참조한 리소스는 서명을 문서화합니다 :'IEnumerable expected, object actual'. 그러나 이것은 잘못된 것입니다. 이 방법이 제공하는 주장은 그 반대입니다. 당신의 예제에서'actual = 6'을 만든다면, 이것은 여러분이 얻는 것입니다 :'예상 : 6을 포함한 콜렉션이 있습니다 : <0, 1, 2, 3, 5> – chiccodoro

+0

글쎄, 'expected'를'collection'으로 이름을 바꿀 수 있고 assertion failed 메시지가 완벽하게 이해 될 것입니다. 즉'Expected : 6을 포함한 콜렉션이 <0, 1, 2, 3, 5> '입니다. assertion failed 메시지를 명시 적으로 지정하는 곳에 'CollectionAssert.Contains'의 다른 재정의 (override)를 사용할 수 있다면 자신 만의 주장을 쓸 것이라고 믿을 수 없습니다. FYI 이것은 우리가 24K 종업원과 수십 페이지의 코딩 표준을 사용하여 회사에서 사용하는 접근 방식이며이 접근 방식은 괜찮은 것으로 간주됩니다. –

2

Or 제약 조건을 사용하여, NUnit과에 내장 할 수있는 방법이있다 :

Assert.That(actual, Is.EqualTo(1).Or.EqualTo(2).Or.EqualTo(3)) 

목록이 더 역동적 경우이 같은 Or의의 목록 구축 할 수 있습니다 :

var expected = new[] { 1, 2, 3 }; 
var constraints = Is.EqualTo(expected[0]); 

for(var i = 1; i < expected.Length; i++) 
    constraints = constraints.Or.EqualTo(expected[i]); 

Assert.That(actual, constraints); 

후자의 대답은 유동적 인 구문에서도 잘 읽지 않지만 역동적 인 건물 또는 제약 조건을 달성합니다. 패트릭 - 쿼크 (patrick-quirk)가 더 많은 읽을 수있는 유체 구문을 얻기 위해 시연 된 사용자 정의 제약 조건에서이를 감쌀 수도 있지만, 이는 당신에게 달려 있습니다.