2016-09-14 4 views
1

私はすでに回答した質問を見てみましたが、私の場合にはなじみのないものなので、このスレッドを開いています。NUnit 3 - TestCaseは 'equal'の場合でもExpectedResultを検証しません。

私はVS 2015の下でNUnit 3を使用しています。ユニットテストをした後、間違ったことが実現しました。期待される結果は、実際には、私が受け取ると期待していたものと同じではありませんが、NUnitはそれを検証しませんでした。

ですか?

以下は、テストを実行するコードです。

public static class DataFactory 
{ 
    public static class Dummy 
    { 
     public static string ContractUrl = ""; 

     public static IEnumerable Objects 
     { 
      get 
      { 
       yield return new TestCaseData(ContractUrl, true, false).Returns(false); 
       yield return new TestCaseData(ContractUrl, "", "Ciao").Returns("Ciao"); 
       yield return new TestCaseData(ContractUrl, Payload.Dummy.TrueRequest, Payload.Dummy.TrueResponse).Returns(Payload.Dummy.TrueResponse); 
      } 
     } 
    } 
} 

public static class Payload 
{ 
    public static class Dummy 
    { 
     public static GetItemsRequest TrueRequest 
     { 
      get 
      { 
       return new GetItemsRequest() { }; 
      } 
     } 

     public static GetItemsResponse TrueResponse 
     { 
      get 
      { 
       return new GetItemsResponse() 
       { 
        Result = true 
       }; 
      } 
     } 
    } 
} 


[DataContract] 
public class GetItemsRequest : ICloneable<GetItemsRequest> 
{ 
    [DataMember] 
    public string QuoteCode { get; set; } 

    [DataMember] 
    public int QuoteRevision { get; set; } 

    [DataMember] 
    public DocumentFormat Format { get; set; } 

    [DataMember] 
    [Description("Nel caso sia False devo inizializzare l'ambiente, ovvero scaricare tutti i documenti in tutte le lingue." + 
       "Viene pilotato dal CRM, che setta a False o True la property nel Request Payload.")] 
    public bool GetContent { get; set; } 

    [DataMember] 
    [Description("Viene usato per indicare se nel GetContent deve essere passato il percorso del documento "+ 
       "(GetRemotePath = true) oppure il contenuto del documento.")] 
    public bool GetRemotePath { get; set; } 

    //Language Code 
    [DataMember] 
    public string Language { get; set; } 

    [DataMember] 
    public List<Product> Products { get; set; } 

    [System.Diagnostics.DebuggerStepThrough] 
    public GetItemsRequest Clone() 
    { 
     return (GetItemsRequest)Cloning.DeepCopy(this); 
    } 
} 


[DataContract] 
public class Product 
{ 
    [DataMember] 
    public string ProductCode { get; set; } 

    [DataMember] 
    public string PositionCode { get; set; } 
} 

[DataContract] 
public class GetItemsResponse 
{ 
    [DataMember] 
    public bool Result { get; set; } 

    [Description("Messaggio d'errore. Si presenta solo se Result = false.")] 
    [DataMember] 
    public string Message { get; set; } 

    [DataMember] 
    public List<TDSContent> Contents { get; set; } 
} 

[DataContract] 
public class TDSContent : Product 
{ 
    [DataMember] 
    public string Language { get; set; } 

    [DataMember] 
    public string TextContent { get; set; } 
} 

、以下の結果得られ単体テスト

[Test] 
    [TestCaseSource(typeof(DataFactory.Dummy), "Objects")] 
    public object Dummy(string contractUrl, object payload, object expectedResult) 
    { 
     return expectedResult; 
    } 

enter image description here

が、これは正常な動作ですか? 期待される結果は、値ではなく参照で一致する必要がありますか?

+0

このページは助けることができる、比較のためのデフォルトの動作を上書きするには、次の – Lorenzo

答えて

0

NUnitが何も知らない型である、GetItemsRequestと比較しているので、最終的にはそのクラスのEqualsメソッド(それはobjectから継承されています)を呼び出すだけです。 According to MSDN、クラスでそれをオーバーライドしなかった場合は、クラスの参照の等価性と値の型のやや複雑な方法を使用します。


これを確認するためにNUnitの腸を詳しく見てみましょう。 you'll see this codeTestMethodCommand.Execute()でダウン:

public override TestResult Execute(TestExecutionContext context) 
{  
    // TODO: Decide if we should handle exceptions here 
    object result = RunTestMethod(context); 

    if (testMethod.HasExpectedResult) 
     NUnit.Framework.Assert.AreEqual(testMethod.ExpectedResult, result); 

    context.CurrentResult.SetResult(ResultState.Success); 
    // TODO: Set assert count here? 
    //context.CurrentResult.AssertCount = context.AssertCount; 
    return context.CurrentResult; 
} 

これは、最終的には(RunTestMethodの内側)テストメソッドを呼び出すコードです。ご覧のように、メソッドの戻り値をとり、それをAssert.AreEqual()に渡します。この主張looks like this

public static void AreEqual(object expected, object actual) 
{ 
    Assert.That(actual, Is.EqualTo(expected), null, null); 
} 

Is.EqualToはちょうどそのApply method looks like thisEqualConstraint、作成します。

public override ConstraintResult ApplyTo<TActual>(TActual actual) 
{ 
    AdjustArgumentIfNeeded(ref actual); 
    return new EqualConstraintResult(this, actual, 
     _comparer.AreEqual(_expected, actual, ref _tolerance)); 
} 

(あなたは別のものを指定していないので、それはあなたのケースになります)、デフォルトで_comparer参照NUnitEqualityComparerであり、その関連部分はAreEqual method looks like this

public bool AreEqual(object x, object y, ref Tolerance tolerance) 
{ 
    if (x == null && y == null) 
     return true; 

    if (x == null || y == null) 
     return false; 

    if (object.ReferenceEquals(x, y)) 
     return true; 

    // Omitted: a whole bunch of checks for specific types that will fail in your case. 

    return x.Equals(y); 
} 

最後の行に実際の比較が行われます。

+0

詳細な回答ありがとうございます。 実際には、結果を検証するために私はカスタムオブジェクト比較関数を使用します。 私のカスタムコンペアーを使用して、ApplyToメソッドをオーバーライドすることができます。コードの 'オーバーライド' は良い音こと : 公共オーバーライドConstraintResult ApplyTo (触覚実際の) {AdjustArgumentIfNeeded(REF実際の) 新しいEqualConstraintResultを返します(実際、 _comparer.AreEqual(_expected、actual、ref _tolerance)); } – Lorenzo

+0

正しい方法で私にそれを上書きする方法を教えてください。それはできないようだ。 – Lorenzo

+0

'TestCaseData'を使用しているときに、カスタム比較関数を指定する方法はありません。アサーションを自分で作成していた場合は、通常、Assert.That(実際、Is.EqualTo(期待).Using(yourComparer))を記述します。フレームワークはそのアサーションを代わりに実行するので、コンマを指定する方法があります。テストを書き直す必要があると思います。 –

3

これは、参照の平等にのみ間接的に関係しています。 falseの場合に注意するように、テストは値オブジェクトに対して完全に機能します。

NUnitは、EqualConstraintを使用して、返された結果と期待される結果を比較します。したがって、あなた自身のコードでAssert.AreEqualとも動作しない限り、比較は成功しません。

この場合、クラスのEqualsメソッドはオーバーライドされていません。したがって、基礎となるobject.Equalsメソッドが使用されます。参照平等は、objectによって実装されているので、それがここにあります。

+0

こんにちはチャーリー、 私はNUnitのスレッドとIにお返事を見てきましたhttps://github.com/nunit/docs/wiki/Custom-Constraintsあなたが助けてくれるなら、あなたのためにいくつかの質問をしてください。 – Lorenzo

関連する問題