流利的断言;结合集合和对象图比较断言
FluentAssertions; combining collection and object graph comparison assertions
我正在尝试使用 FluentAssertions 来组合集合和对象图比较断言。
我有以下 class.
public class Contract
{
public Guid Id { get; set; }
public string Name { get; set; }
}
在集合中返回,就像这样。
ICollection<Contract> contracts = factory.BuildContracts();
然后我想确保该集合仅包含特定的 Contract
个对象。
contracts.Should().Contain(new Contract() { Id = id1, Name = "A" });
这行不通,我相信是因为 Contain
使用的是 object.Equals
而不是对象图比较(由 ShouldBeEquivalentTo
提供)。
我还需要断言该集合不包含特定对象,即
contracts.Should().NotContain(new Contract() { Id = id2, Name = "B" });
实际上给定一个包含未知数量项目的集合,我想确保;它包含许多特定项目,并且它不包含许多特定项目。
能否使用FluentAssertions提供的函数实现?
附带说明一下,出于此处讨论的原因,我不想覆盖 object.Equals
。
你可以覆盖你的合同 Equals
然后将被使用,你的单元测试应该顺利通过。
如果您使用的是随机 Guid,这可能是个问题,但您似乎使用的是预定义的。
试试以下方法:
protected bool Equals(Contract other)
{
return Id.Equals(other.Id) && string.Equals(Name, other.Name);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((Contract) obj);
}
public override int GetHashCode()
{
unchecked
{
return (Id.GetHashCode()*397) ^ (Name != null ? Name.GetHashCode() : 0);
}
}
如您所见,它通过了测试:
据我从文档和我使用该框架的经验来看,它确实使用了 object.Equals
。
在这种情况下,我倾向于使用 the collections documentation for v3.0 and higher 中引用的表达式谓词。
以下示例展示了如何确保集合仅包含特定的 Contract
对象并断言集合不包含特定的对象。
[TestMethod]
public void FluentAssertions_Should_Validate_Collections() {
//Arrange
var id1 = Guid.NewGuid();
var id2 = Guid.NewGuid();
var list = new List<Contract>{
new Contract() { Id = id1, Name = "A" },
new Contract() { Id = Guid.NewGuid(), Name = "B"}
};
var factoryMock = new Mock<IContractFactory>();
factoryMock.Setup(m => m.BuildContracts()).Returns(list);
var factory = factoryMock.Object;
//Act
var contracts = factory.BuildContracts();
//Assert
contracts.Should()
.HaveCount(list.Count)
.And.Contain(c => c.Id == id1 && c.Name == "A")
.And.NotContain(c => c.Id == id2 && c.Name == "B");
}
作为 Nkosi's 答案的替代方案,您仍然可以通过构建期望来使用 ShouldBeEquivalentTo
。
我正在尝试使用 FluentAssertions 来组合集合和对象图比较断言。
我有以下 class.
public class Contract
{
public Guid Id { get; set; }
public string Name { get; set; }
}
在集合中返回,就像这样。
ICollection<Contract> contracts = factory.BuildContracts();
然后我想确保该集合仅包含特定的 Contract
个对象。
contracts.Should().Contain(new Contract() { Id = id1, Name = "A" });
这行不通,我相信是因为 Contain
使用的是 object.Equals
而不是对象图比较(由 ShouldBeEquivalentTo
提供)。
我还需要断言该集合不包含特定对象,即
contracts.Should().NotContain(new Contract() { Id = id2, Name = "B" });
实际上给定一个包含未知数量项目的集合,我想确保;它包含许多特定项目,并且它不包含许多特定项目。
能否使用FluentAssertions提供的函数实现?
附带说明一下,出于此处讨论的原因,我不想覆盖 object.Equals
。
你可以覆盖你的合同 Equals
然后将被使用,你的单元测试应该顺利通过。
如果您使用的是随机 Guid,这可能是个问题,但您似乎使用的是预定义的。
试试以下方法:
protected bool Equals(Contract other)
{
return Id.Equals(other.Id) && string.Equals(Name, other.Name);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((Contract) obj);
}
public override int GetHashCode()
{
unchecked
{
return (Id.GetHashCode()*397) ^ (Name != null ? Name.GetHashCode() : 0);
}
}
如您所见,它通过了测试:
据我从文档和我使用该框架的经验来看,它确实使用了 object.Equals
。
在这种情况下,我倾向于使用 the collections documentation for v3.0 and higher 中引用的表达式谓词。
以下示例展示了如何确保集合仅包含特定的 Contract
对象并断言集合不包含特定的对象。
[TestMethod]
public void FluentAssertions_Should_Validate_Collections() {
//Arrange
var id1 = Guid.NewGuid();
var id2 = Guid.NewGuid();
var list = new List<Contract>{
new Contract() { Id = id1, Name = "A" },
new Contract() { Id = Guid.NewGuid(), Name = "B"}
};
var factoryMock = new Mock<IContractFactory>();
factoryMock.Setup(m => m.BuildContracts()).Returns(list);
var factory = factoryMock.Object;
//Act
var contracts = factory.BuildContracts();
//Assert
contracts.Should()
.HaveCount(list.Count)
.And.Contain(c => c.Id == id1 && c.Name == "A")
.And.NotContain(c => c.Id == id2 && c.Name == "B");
}
作为 Nkosi's 答案的替代方案,您仍然可以通过构建期望来使用 ShouldBeEquivalentTo
。