单元测试-xUnit
Assert常用方法
名称 | 描述 |
---|---|
Eqalexpected.result) | 断言结果与期望值相等。该方法的重载版本用于比较不同的类型和集合。该方法的另一种版本接受一个额外参数 该对象实现了用于比较对象的IEqualityComparer接口 |
NotEqual(expected,result) | 断言结果不等于期望值 |
True(result) | 断言结果为true |
False(result) | 断言结果为false |
IsType(expected,result) | 断言结果为指定类型 |
IsNotType(expected,result) | 断言结果不为指定类型 |
IsNull(result) | 断言结果为null |
IsNotNull(result) | 断言结果不为null |
InRange(result,low,high) | 断言结果介于low和high |
NotInRange(result,low,high) | 断言结果不介于low和high |
Throws(exception,expression) | 断言指定的表达式抛出指定的异常类型 |
客户需求:我要在首页看到所有在职的员工信息
快速构建一个MVC项目
1、在Models文件夹中添加Staff.cs实体类
public class Staff
{public int Id { get; set; }public string Name { get; set; }public string State { get; set; }public int Age { get; set; }public IEnumerable<Staff> GetAllStaff(){Staff[] staffs = new Staff[]{new Staff(){ Id = 1, Name = "张三", State = "在职", Age = 18 },new Staff(){ Id = 2, Name = "李四", State = "离职", Age = 20 },new Staff(){ Id = 10, Name = "王五", State = "在职", Age = 36 },new Staff(){ Id = 8, Name = "血友病", State = "在职", Age = 18 }};return staffs;}
}
2、HomeController中的Index方法内容:
public IActionResult Index()
{return View(new Staff().GetAllStaff().Where(x => x.State == "在职 "));
}
3、创建单元测试-xUnit
右键解决方案=>添加=>新建项目
找到xUnit测试项目:该项目的约定命名为 要测试的应用程序名加上.Tests
4、编写测试内容
修改UnitTest1.cs文件的名称,改为HomeControllerTests
在HomeControllerTests类中编写一个方法,该方法针对于Home控制器的Index方法
public void IndexActionModelIsComplete()
{//获取Home控制器var controll = new HomeController();//获取Home控制器Index方法的返回值var model = (controll.Index() as ViewResult).ViewData.Modelas IEnumerable<Staff>;//方法:预料值与实际值进行比较//参数1:你预料的理想状态值//参数2:实际上你代码返回的值Assert.Equal(new Staff().GetAllStaff().Where(x => x.State == "在职"),model);
}
在Assert.Equal中的两个参数如果是Int、string、bool这种类型的话可以直接进行比较
但是这里两个参数都是IEnumerable类型,进行比较的话,需要一定的逻辑,所以我们需要使用第三个参数来进行逻辑比较
然而第三个参数是IEqualityComparer (等式比较器) 类型,所以我们要使用实现了该接口的类
那么我们就定义一个类实现该接口
public class StaffComparer : IEqualityComparer<Staff>
{//预料值与实际值比较的逻辑在这个方法中写入public bool Equals(Staff x, Staff y){return x.Name == y.Name && x.State == y.State && x.Id == y.Id;}public int GetHashCode([DisallowNull] Staff obj){return obj.GetHashCode();}
}
之后在HomeControllerTests的IndexActionModelIsComplete方法修改Assert.Equal
Assert.Equal(new Staff().GetAllStaff().Where(x => x.State == "在职"),model,new StaffComparer()
);
5、进行测试
上方视图中找到测试资源管理器
执行测试
测试失败?什么原因呢?哦,原来是我们实际的值连一个都没有,那么我们就可以去Home控制器中的Index方法查找原因
原来是我们这里的判断多了一个空格,我们把空格删除再次进行测试
6、如果我们有很多种对象需要比较,那么逻辑该怎么办?
目前我们的逻辑比较只是针对于Staff对象,想多再次比较另外一个类型,我们又得创建一个类,再次编写逻辑,这样显得很笨重
那么我们进行一次升级,代码如下:
public class Comparer
{public static Comparer<B> Get<B>(Func<B, B, bool> func){//创建Comparer<T>类型return new Comparer<B>(func);}
}public class Comparer<T> : Comparer, IEqualityComparer<T>
{private Func<T, T, bool> func;//构造器public Comparer(Func<T, T, bool> func) => this.func = func;public bool Equals(T? x, T? y){return func(x, y);}public int GetHashCode([DisallowNull] T obj){return obj.GetHashCode();}
}
Assert.Equal更改:
Assert.Equal(new Staff().GetAllStaff().Where(x => x.State == "在职"),model,Comparer.Get<Staff>((a, b) => a.Name == b.Name && a.State == b.State && a.Id == b.Id)
);