使用Nunit或Microsoft.VisualStudio.TestTools.UnitTesting。现在我的断言失败了。
[TestMethod]
public void GivenEmptyBoardExpectEmptyBoard()
{
var test = new Board();
var input = new Board()
{
Rows = new List<Row>()
{
new Row(){Cells = new List<int>(){0,0,0,0}},
new Row(){Cells = new List<int>(){0,0,0,0}},
new Row(){Cells = new List<int>(){0,0,0,0}},
new Row(){Cells = new List<int>(){0,0,0,0}},
}
};
var expected = new Board()
{
Rows = new List<Row>()
{
new Row(){Cells = new List<int>(){0,0,0,0}},
new Row(){Cells = new List<int>(){0,0,0,0}},
new Row(){Cells = new List<int>(){0,0,0,0}},
new Row(){Cells = new List<int>(){0,0,0,0}},
}
};
var lifeOrchestration = new LifeOrchestration();
var actual = lifeOrchestration.Evolve(input);
Assert.AreEqual(expected, actual);
}
答案 0 :(得分:16)
您有两个不同的Board
个实例,因此您对Assert.AreEqual
的调用将失败。即使它们的全部内容看起来相同,您也要比较参考,而不是基础值。
您必须指定使两个Board
实例相等的内容。
您可以在测试中执行此操作:
Assert.AreEqual(expected.Rows.Count, actual.Rows.Count);
Assert.AreEqual(expected.Rows[0].Cells[0], actual.Rows[0].Cells[0]);
// Lots more tests of equality...
或者你可以在课堂上做到这一点:(注意我是在飞行中写的 - 你要调整它)
public class Board
{
public List<Row> Rows = new List<Row>();
public override bool Equals(object obj)
{
var board = obj as Board;
if (board == null)
return false;
if (board.Rows.Count != Rows.Count)
return false;
return !board.Rows.Where((t, i) => !t.Equals(Rows[i])).Any();
}
public override int GetHashCode()
{
// determine what's appropriate to return here - a unique board id may be appropriate if available
}
}
public class Row
{
public List<int> Cells = new List<int>();
public override bool Equals(object obj)
{
var row = obj as Row;
if (row == null)
return false;
if (row.Cells.Count != Cells.Count)
return false;
if (row.Cells.Except(Cells).Any())
return false;
return true;
}
public override int GetHashCode()
{
// determine what's appropriate to return here - a unique row id may be appropriate if available
}
}
答案 1 :(得分:10)
我曾经覆盖了getHasCode和equals,但我从不喜欢它,因为我不想为了单元测试而改变我的生产代码。 这也是一种痛苦。
然后我过于反思来比较那些侵入性较小的物体......但那是很多工作(很多角落的情况)
最后我使用:
http://www.nuget.org/packages/DeepEqual/
效果很好。
答案 2 :(得分:7)
ExpectedObjects可以帮助您按属性值比较相等性。它支持:
我喜欢ExpectedObjects,因为我只需要调用2个API来断言比较对象的相等性:
答案 3 :(得分:7)
我想要一个不需要添加依赖项的解决方案,使用VS单元测试,比较两个对象的字段值,并告诉我所有不相等的字段。这就是我提出的。请注意,它也可以扩展为使用属性值。
就我而言,这适用于比较某些文件解析逻辑的结果,以确保两个技术上“不同”的条目具有相同值的字段。
public class AssertHelper
{
public static void HasEqualFieldValues<T>(T expected, T actual)
{
var failures = new List<string>();
var fields = typeof(T).GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
foreach(var field in fields)
{
var v1 = field.GetValue(expected);
var v2 = field.GetValue(actual);
if (v1 == null && v2 == null) continue;
if(!v1.Equals(v2)) failures.Add(string.Format("{0}: Expected:<{1}> Actual:<{2}>", field.Name, v1, v2));
}
if (failures.Any())
Assert.Fail("AssertHelper.HasEqualFieldValues failed. " + Environment.NewLine+ string.Join(Environment.NewLine, failures));
}
}
[TestClass]
public class AssertHelperTests
{
[TestMethod]
[ExpectedException(typeof(AssertFailedException))]
public void ShouldFailForDifferentClasses()
{
var actual = new NewPaymentEntry() { acct = "1" };
var expected = new NewPaymentEntry() { acct = "2" };
AssertHelper.HasEqualFieldValues(expected, actual);
}
}
答案 4 :(得分:2)
对于琐碎的对象(例如域对象或DTO或实体),您只需将两个实例序列化为一个字符串并比较该字符串:
var object1Json = JsonConvert.SerializeObject(object1);
var object2Json = JsonConvert.SerializeObject(object2);
Assert.AreEqual(object1Json, object2Json);
这当然有很多注意事项,因此请评估JSON是否包含您应该比较的期望值。
例如,如果您的类包含非托管资源或其他不可序列化的属性,则将无法正确比较这些属性。默认情况下,它也只序列化公共属性。
答案 5 :(得分:1)
由于尚未在此问题上提到任何人,因此还有一些其他采用良好的库可以帮助解决此问题:
Fluent Assertions-参见object graph comparison
actual.Should().BeEquivalentTo(expected);
Likeness<MyModel, MyModel>(actual).ShouldEqual(expected);
我个人更喜欢Fluent断言,因为它在成员排除等方面提供了更大的灵活性,并且支持开箱即用地比较嵌套对象。
希望这会有所帮助!
答案 6 :(得分:0)
Assert方法依赖于对象的Equals和GetHashcode。你可以实现它,但如果在单元测试之外不需要这个对象相等,我会考虑比较对象上的各个基本类型。 看起来这些对象很简单,并且不能保证等于等等。