C#单元测试失败,即使AssertAreEqual看起来相等
我有一个单元测试,如下所示:C#单元测试失败,即使AssertAreEqual看起来相等,c#,asp.net-mvc,unit-testing,C#,Asp.net Mvc,Unit Testing,我有一个单元测试,如下所示: [TestMethod] public void ShowPreviousGuessesSetsTheModelPropertyToTheListOfGuessObjectsStoredInTheGuessingGameObject() { //Arrange //First, set up a game and store the expected result var theGame = new GuessingGame(); L
[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);
}
public GuessingGame()
{
//Set up the GuessingGame object
this.Guesses = new List<Guess>();
}
[TestMethod]
public void show previous guesses模型属性到存储在GuessingGameObject()中的ListFGUES对象
{
//安排
//首先,设置游戏并存储预期结果
var theGame=新猜游戏();
List expectedResult=theGame.showGuessMade();
//接下来,使用存储在会话中的此游戏设置FakeHttpContext
var theContext=new FakeHttpContext();
var theKey=“游戏状态”;
context.Session.Add(按键,游戏);
//现在,使用此上下文设置控制器
var控制器=新的Exercise09Controller();
var request=new System.Web.Routing.RequestContext(context,new System.Web.Routing.routedData());
controller.ControllerContext=new System.Web.Mvc.ControllerContext(请求,控制器);
//表演
var result=controller.ShowPreviousGuesses();
//断言
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;
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Web;
名称空间Prigmore2013_01.Models
{
公开课猜谜游戏
{
公共列表目标{get;set;}
公共列表猜测{get;set;}
公开列表showGuessMade()
{
var listRange=新列表();
如果(listRange!=null)
{
返回列表范围;
}
返回列表范围;
}
}
}
我已经运行了测试,我得到了错误:
Message: AssertAreEqual failed.
Expected:<System.Collections.Generic.List`1[Prigmore2013_01.Models.Guess]>.
Actual:<System.Collections.Generic.List`1[Prigmore2013_01.Models.Guess]>.
消息:AssertAreEqual失败。
预期:。
实际值:。
有人能给我解释一下为什么这个单元测试失败了,即使预期值==与实际值一致?我如何修复它以使我的单元测试通过?您需要做两件事,第一件是使用,第二件是覆盖
Guess
类中的Equals
和GetHashCode
方法
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();
}
}
您需要做两件事,第一件是使用,第二件是重写
Guess
类中的Equals
和GetHashCode
方法
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();
}
}
看看您在断言中比较的内容:
//Assert
Assert.AreEqual(expectedResult, result.Model);
expectedResult
是调用游戏的结果。ShowGuessMade()
,而result
是调用控制器的结果。ShowPreviousGuesses()
这是两个不同的列表。请注意,尽管它们可能都是空的,或者包含相同顺序的相同元素,但这并不意味着它们相等——从语义上讲,可能是等价的——但并不相等。在这种情况下,相等(对于引用类型)通常意味着“此对象是否与此其他对象完全相同”
正如@MichaelPerrenoud在上面所说的,当您试图断言列表的等价性时,您需要使用
CollectionAssert.AreEqual
。查看您在断言中比较的内容:
//Assert
Assert.AreEqual(expectedResult, result.Model);
expectedResult
是调用游戏的结果。ShowGuessMade()
,而result
是调用控制器的结果。ShowPreviousGuesses()
这是两个不同的列表。请注意,尽管它们可能都是空的,或者包含相同顺序的相同元素,但这并不意味着它们相等——从语义上讲,可能是等价的——但并不相等。在这种情况下,相等(对于引用类型)通常意味着“此对象是否与此其他对象完全相同”
正如@MichaelPerrenoud上面所说的,当您试图断言列表的等价性时,您需要使用CollectionAssert.AreEqual
。当打印出“预期”和“实际”值时,测试运行程序调用对象上的ToString()
。默认情况下,引用类型打印出完全限定的类型名称,在您的示例中:System.Collections.Generic.List`1[Prigmore2013\u 01.Models.Guess]
您感到困惑,因为这两种情况下打印出的字符串相同;这是因为这两个对象是同一个类的实例(通俗地说是List
),这就是它们打印出相同标识字符串的原因。但正如其他人所指出的,它们是两个不同的对象,存储在两个不同的内存位置。引用类型上的Assert.AreEqual将执行“引用相等”——不是“这些对象的内容相同”,而是“这两个变量引用相同的内存位置吗?”
正如其他人所指出的那样,.Net framework有一个有用的工具来完成您想要做的事情,比较两个列表的内容(CollectionAssert.AreEqual
);我只是想提供更多的背景知识,并解决一些在开始时让我感到困惑的问题。当打印出“预期”和“实际”值时,测试运行程序对对象调用ToString()
。默认情况下,引用类型打印出完全限定的类型名称,在您的示例中:System.Collections.Generic.List`1[Prigmore2013\u 01.Models.Guess]
您感到困惑,因为这两种情况下打印出的字符串相同;这是因为这两个对象是同一个类的实例(通俗地说是List
),这就是它们打印出相同标识字符串的原因。但正如其他人所指出的,它们是两个不同的对象,存储在两个不同的内存位置。引用类型上的Assert.AreEqual将执行“引用相等”——不是“这些对象的内容相同”,而是“这两个变量引用相同的内存位置吗?”
正如其他人所指出的那样,.Net framework有一个有用的工具来完成您想要做的事情,比较两个列表的内容(
CollectionAssert.AreEqual
);我只是想提供更多的背景知识,并解决一些在我刚开始时让我感到困惑的问题。没有按如下方式设置构造函数:
[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);
}
public GuessingGame()
{
//Set up the GuessingGame object
this.Guesses = new List<Guess>();
}
没有按如下方式设置构造函数