改进断言的一种方法是将比较提取到自定义IEquivalencyStep 中,以指导如何比较Customer 和Employee。
它由两部分组成:
-
CanHandle 确定此比较何时适用,并且
-
Handle 执行自定义比较。
public class CustomerEmployeeComparer : IEquivalencyStep
{
public bool CanHandle(IEquivalencyValidationContext context,
IEquivalencyAssertionOptions config)
{
return context.Subject is Customer
&& context.Expectation is Employee;
}
public bool Handle(IEquivalencyValidationContext context, IEquivalencyValidator
parent, IEquivalencyAssertionOptions config)
{
var customer = (Customer)context.Subject;
var employee = (Employee)context.Expectation;
customer.Name.Should().Be(employee.FirstName, context.Because, context.BecauseArgs);
customer.Age.Should().Be(employee.Age, context.Because, context.BecauseArgs);
return true;
}
}
要在断言中使用CustomerEmployeeComparer,请通过在BeEquivalentTo 的EquivalencyAssertionOptions config 参数上调用Using(new CustomerEmployeeComparer()) 来添加它。
注意:由于您的示例需要按顺序比较两个列表,因此我在下面的示例中添加了WithStrictOrdering()。
[TestMethod]
public void CompareCustomersAndEmployeesWithCustomEquivalencyStep()
{
// Arrange
var customers = new[] {
new Customer { Name = "John", Age = 42 },
new Customer { Name = "Mary", Age = 43 }
};
var employees = new[] {
new Employee { FirstName = "John", Age = 42 },
new Employee { FirstName = "Mary", Age = 43 }
};
// Act / Assert
customers.Should().BeEquivalentTo(employees, opt => opt
.Using(new CustomerEmployeeComparer())
.WithStrictOrdering());
}
public class Employee
{
public string FirstName { get; set; }
public int Age { get; set; }
}
public class Customer
{
public string Name { get; set; }
public int Age { get; set; }
}
将第一个 Employee 的名称更改为 Jonathan,现在给出以下失败消息:
Message: Expected item[0] to be "Jonathan" with a length of 8, but "John" has a length of 4, differs near "hn" (index 2).
With configuration:
- Use declared types and members
- Compare enums by value
- Include all non-private properties
- Include all non-private fields
- Match member by name (or throw)
- Without automatic conversion.
- UnitTestProject15.CustomerEmployeeComparer
- Without automatic conversion.
- Always be strict about the collection order
对于任何感兴趣的人,有一个相关的未解决问题是关于覆盖要比较的属性。
https://github.com/fluentassertions/fluentassertions/issues/535