我有一个类库,它包含以下模型和方法
型:
public class Employee {
public int EmpId { get; set; }
public string Name { get; set; }
}
方法:
public class EmployeeService {
public List<Employee> GetEmployee() {
return new List<Employee>() {
new Employee() { EmpId = 1, Name = "John" },
new Employee() { EmpId = 2, Name = "Albert John" },
new Employee() { EmpId = 3, Name = "Emma" },
}.Where(m => m.Name.Contains("John")).ToList();
}
}
我有一个测试方法
[TestMethod()]
public void GetEmployeeTest() {
EmployeeService obj = new EmployeeService();
var result = obj.GetEmployee();
Xunit.Assert.Collection<Employee>(result, m => Xunit.Assert.Contains("John",m.Name));
}
我收到异常消息
Assert.Collection() Failure
Collection: [Employee { EmpId = 1, Name = "John" }, Employee { EmpId = 2, Name = "Albert John" }]
Expected item count: 1
Actual item count: 2
我的要求是检查所有items.Name
是否应包含子字符串"John"。请协助我如何使用Xunit.Assert.Collection
进行检查
看来Assert.Collection只使用每个元素检查器一次。因此,对于您的测试,以下工作:
如果序列result
正好有两个元素:
[Fact]
public void GetEmployeeTest()
{
EmployeeService obj = new EmployeeService();
var result = obj.GetEmployee();
Assert.Collection(result, item => Assert.Contains("John", item.Name),
item => Assert.Contains("John", item.Name));
}
如果有很多元素,请将Assert
更改为
Assert.All(result, item => Assert.Contains("John", item.Name));
应该给你你期待的结果。
这是对Ayb4btu对那些对集合中项目的顺序不感兴趣的人的答案的扩展。
以下方法基于原始的 XUnit 实现,并允许您使用非常相似的接口进行测试:
public static class TestExpect
{
public static void CollectionContainsOnlyExpectedElements<T>(IEnumerable<T> collectionToTest, params Func<T, bool>[] inspectors)
{
int expectedLength = inspectors.Length;
T[] actual = collectionToTest.ToArray();
int actualLength = actual.Length;
if (actualLength != expectedLength)
throw new CollectionException(collectionToTest, expectedLength, actualLength);
List<Func<T, bool>> allInspectors = new List<Func<T, bool>>(inspectors);
int index = -1;
foreach (T elementToTest in actual)
{
try
{
index++;
Func<T, bool> elementInspectorToRemove = null;
foreach (Func<T, bool> elementInspector in allInspectors)
{
if (elementInspector.Invoke(elementToTest))
{
elementInspectorToRemove = elementInspector;
break;
}
}
if (elementInspectorToRemove != null)
allInspectors.Remove(elementInspectorToRemove);
else
throw new CollectionException(collectionToTest, expectedLength, actualLength, index);
}
catch (Exception ex)
{
throw new CollectionException(collectionToTest, expectedLength, actualLength, index, ex);
}
}
}
}
这里的区别在于,对于集合
string[] collectionToTest = { "Bob", "Kate" };
以下两行都不会产生CollectionException
TestExpect.CollectionContainsOnlyExpectedElements(collectionToTest, x => x.Equals("Bob"), x => x.Equals("Kate"));
TestExpect.CollectionContainsOnlyExpectedElements(collectionToTest, x => x.Equals("Kate"), x => x.Equals("Bob"));
而使用 Assert.Collection
- 只有上述两行中的第一行才能工作,因为检查员的集合按顺序进行评估。
使用此方法可能会对性能产生影响,但如果只测试相当小的集合(因为您可能在单元测试中(,则永远不会注意到差异。
使用 Assert.Contains(result, item => item.Name == "John");