2013-12-09 32 views
0

我有一個單元測試如下:C#單位測試失敗,即使AssertAreEqual似乎是相等

[TestMethod] 
public void ShowPreviousGuessesSetsTheModelPropertyToTheListOfGuessObjectsStoredInTheGuessingGameObject() 
{ 
    //Arrange 
    //First, set up a game and store the expected result 
    var theGame = new GuessingGame(); 
    List<Guess> expectedResult = theGame.ShowGuessesMade(); 
    //Next, set up a FakeHttpContext with this game stored in the Session 
    var theContext = new FakeHttpContext(); 
    var theKey = "GameState"; 
    theContext.Session.Add(theKey, theGame); 
    //Now, set up a controller with this context 
    var controller = new Exercise09Controller(); 
    var request = new System.Web.Routing.RequestContext(theContext, new System.Web.Routing.RouteData()); 
    controller.ControllerContext = new System.Web.Mvc.ControllerContext(request, controller); 

    //Act 
    var result = controller.ShowPreviousGuesses(); 

    //Assert 
    Assert.AreEqual(expectedResult, result.Model); 
} 

而從上面的代碼我已經作出了以下類:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 

namespace Prigmore2013_01.Models 
{ 
    public class GuessingGame 
    { 

     public List<int> Target { get; set; } 
     public List<int> Guesses { get; set; } 

     public List<Guess> ShowGuessesMade() 
     { 
      var listRange = new List<Guess>(); 

      if (listRange != null) 
      { 
       return listRange; 
      } 
       return listRange; 
     } 
    } 
} 

我已運行測試,我得到的錯誤:

Message: AssertAreEqual failed. 

Expected:<System.Collections.Generic.List`1[Prigmore2013_01.Models.Guess]>. 

Actual:<System.Collections.Generic.List`1[Prigmore2013_01.Models.Guess]>. 

會有人能向我解釋爲什麼這個單元測試是失敗的,即使日e期望值==到實際值?我該如何解決這個問題,以便我的單元測試通過?

回答

0

具有不建立一個構造函數如下:

public GuessingGame() 
     { 
      //Set up the GuessingGame object 
      this.Guesses = new List<Guess>(); 
     } 

我返回對象的不同實例。創建構造函數後,我可以返回正確的列表集合,然後在控制器中直接訪問屬性:

public ViewResult ShowPreviousGuesses() 
     { 
    GuessingGame theGame = this.Session["GameState"] as GuessingGame; 

    return View("Index", theGame.Guesses); 
} 
4

您需要做兩件事,第一次使用CollectionAssert.AreEqual,第二次,覆蓋Guess類中的EqualsGetHashCode方法。

public class Guess 
{ 
    ... 

    public override bool Equals(object obj) 
    { 
     // determine equality 
    } 

    public override int GetHashCode() 
    { 
     // if you have an INT primary key here, it would be good to use that 
     // Example: return this.IntProperty.GetHashCode(); 
    } 
} 
0

看看你的說法比較什麼:

//Assert 
Assert.AreEqual(expectedResult, result.Model); 

expectedResult是調用theGame.ShowGuessesMade()的結果,而result是調用controller.ShowPreviousGuesses()

的結果,這是兩個不同的列表。請注意,即使它們都可能爲空,或者包含相同順序的元素,但它們並不會使它們相等 - 在語義上,它可能 - 但不相等 - 等效於。在這種情況下的平等(對於參考類型)通常意味着「該對象與該另一個對象完全相同」。

正如@MichaelPerrenoud上面所說的,當你試圖聲明列表的等價性時,你會想要使用CollectionAssert.AreEqual

1

當打印出「預期」和「實際」值時,測試運行程序在對象上調用ToString()。默認情況下,引用類型打印完全限定類型名稱,在您的情況下:System.Collections.Generic.List`1[Prigmore2013_01.Models.Guess]

你很困惑,因爲這會在兩種情況下打印出相同的字符串;這是因爲這兩個對象是同一類的實例(通俗地說,List<Guess>),這就是它們打印出相同標識字符串的原因。但正如其他人指出的那樣,它們是兩個不同的對象,存儲在兩個不同的存儲位置。引用類型上的Assert.AreEqual將執行「引用相等」 - 不是「這些對象的內容相同」,而是「這兩個變量引用同一個內存位置?」正如其他人所指出的,.Net框架有一個有用的工具來完成你想要做的事情,比較兩個列表的內容(CollectionAssert.AreEqual);我只是想提供一些更多的背景知識,並解決我在開始時遇到的困惑。