xUnit.net的简单用法,包含结合moq来模拟数据访问层操作

0x01 前言

单元测试,总是伴随着我们的开发过程,优劣自行google。当然呢,不排除有些公司是不做单元测试的,

但是呢,学多一点东西用来防身还是可以的。

 

0x02 简单的Demo

写个两数求和的方法,来进行简单的测试。

 1 namespace Catcher.Lib
 2 {
 3     public class Method
 4     {
 5         public int Add(int num1,int num2)
 6         {
 7             return num1 + num2;
 8         }
 9     }
10 }

 

新建一个测试项目,添加xunit的相关引用以及我们测试方法所在的程序。

 

编写测试类MethodTest

 1 using Xunit;
 2 namespace Catcher.Lib.Test
 3 {
 4     public class MethodTest
 5     {
 6         Method method = new Method();
 7         [Fact]
 8         public void add_two_integers_should_success()
 9         {
10             int num1 = 3;
11             int num2 = 5;
12             int expected = 8;
13             int actual = method.Add(num1,num2);
14             Assert.Equal(expected,actual);
15         }
16     }
17 }

 

打开测试窗口,运行测试,看看测试结果

 

OK,测试通过。

注:要通过NuGet安装xunit.runner.visualstudio才可以看到测试窗口!

 

0x03 结合Moq来模拟数据访问层的操作

添加对应数据访问层的接口和类,以及模型(这里没有将模型单独抽出来。)

 

我在这里添加了一个IUserDAL接口和UserDAL类

IUserDAL具体如下

 1 using Catcher.Lib.Model;
 2 using System.Collections.Generic;
 3 namespace Catcher.Lib
 4 {
 5     public interface IUserDAL
 6     {
 7         IList<UserInfo> GetAllUsers();
 8         bool AddUser(UserInfo user);
 9         UserInfo GetUser(int id);       
10     }
11 }

 

UserDAL具体如下

 1 using Catcher.Lib.Model;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 namespace Catcher.Lib.Implement
 5 {
 6     public class UserDAL : IUserDAL
 7     {
 8         public bool AddUser(UserInfo user)
 9         {
10             using (DB db = new DB())
11             {
12                 db.UserInfoes.Add(user);
13                 return db.SaveChanges() > 0;
14             }
15         }
16         public IList<UserInfo> GetAllUsers()
17         {
18             using (DB db = new DB())
19             {
20                 return db.UserInfoes.ToList();
21             }
22         }
23         public UserInfo GetUser(int id)
24         {
25             using (DB db = new DB())
26             {
27                 return db.UserInfoes.Find(id);
28             }
29         }
30     }
31 }  

 

都是些简单的操作,用到了EF,不做过多解释。

 

在测试项目添加一个UserDALTest的测试类。

 

 1 using Catcher.Lib.Model;
 2 using Moq;
 3 using System;
 4 using System.Collections.Generic;
 5 using Xunit;
 6 namespace Catcher.Lib.Test
 7 {
 8     public class UserDALTest
 9     {
10         private List<UserInfo> _userList;
11         private UserInfo _user;
12         public UserDALTest()
13         {
14            //fake data  
15             _userList = new List<UserInfo>();
16             _userList.Add(new UserInfo { UserID = 1, UserName="catcher", UserIsActive=true });
17             _userList.Add(new UserInfo { UserID = 2, UserName = "hawk", UserIsActive = false });
18             _user = new UserInfo() { UserID=3, UserIsActive=true, UserName = "tom" }; 
19         }
20         [Fact]
21         public void get_all_users_should_success()
22         {
23             //arrange
24             var fakeObject = new Mock<IUserDAL>();
25             fakeObject.Setup(x=>x.GetAllUsers()).Returns(_userList);
26             //act
27             var res = fakeObject.Object.GetAllUsers();
28             //assert
29             Assert.Equal(2,res.Count);
30         }
31         [Fact]
32         public void add_a_user_should_success()
33         {
34             var fakeObject = new Mock<IUserDAL>();
35       
36             fakeObject.Setup(x => x.AddUser(It.IsAny<UserInfo>())).Returns(true);
37             var res =  fakeObject.Object.AddUser(_user);
38             Assert.Equal<bool>(true,res);
39         }
40         [Fact]
41         public void add_a_user_should_fail()
42         {
43             var fakeObject = new Mock<IUserDAL>();
44             fakeObject.Setup(x => x.AddUser(It.IsAny<UserInfo>())).Returns(false);
45             var res = fakeObject.Object.AddUser(_user);
46             Assert.Equal<bool>(false, res);
47         }
48         [Fact]
49         public void get_a_user_by_valid_id_should_success()
50         {
51             var fakeObject = new Mock<IUserDAL>();
52             fakeObject.Setup(x=>x.GetUser(It.IsAny<int>())).Returns(_user);
53             var res = fakeObject.Object.GetUser(3);
54             Assert.Equal(3,res.UserID);
55             Assert.Equal("tom",res.UserName);
56             Assert.Equal(true,res.UserIsActive);
57         }
58         [Fact]
59         public void get_a_user_by_invalid_id_should_throw_exception()
60         {
61             var fakeObject = new Mock<IUserDAL>();
62             fakeObject.Setup(x => x.GetUser(It.IsAny<int>())).Throws(new NullReferenceException());           
63             Assert.Throws<NullReferenceException>(()=> fakeObject.Object.GetUser(4));               
64         }
65     }
66 }

 

这里对上面的UserDAL进行简单的说明,

在构造函数中制造了一个模拟的数据,

get_all_users_should_success  测试方法是测试GetAllUsers方法的。

add_a_user_should_success  测试方法是测试AddUser方法的,这个是添加成功的测试。

add_a_user_should_fail  测试方法是测试AddUser方法的,这个是添加失败的测试。

get_a_user_by_valid_id_should_success  测试方法是测试GetUser方法的,这个是查询成功的测试。

get_a_user_by_invalid_id_should_throw_exception  测试方法是测试GetUser方法的,这个是查询抛出异常的测试。

 

注:测试方法的命名应尽可能包含其操作与结果(个人看法)。

 

运行测试效果如下:

 

 

0x04 写在最后

 

平时要养成编写单元测试的好习惯。

 

版权声明:本文为catcher1994原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/catcher1994/p/5498530.html