HTML5技术

C#单元测试,带你快速入门 - 农码一生(2)

字号+ 作者:H5之家 来源:H5之家 2017-05-18 16:00 我要评论( )

新建一个类,用来测试。这个Create会使用仓储操作数据库。这里不希望实际操作数据库,以达到快速测试执行。 [Fact]public void Create_Ok(){IStudentRepositories studentRepositories = new StubStudentRepositori

新建一个类,用来测试。这个Create会使用仓储操作数据库。这里不希望实际操作数据库,以达到快速测试执行。

[Fact] public void Create_Ok() { IStudentRepositories studentRepositories = new StubStudentRepositories(); StudentService service = new StudentService(studentRepositories); var isCreateOk = service.Create(null); Assert.True(isCreateOk); } public class StubStudentRepositories : IStudentRepositories { public void Add(Student model) { } }


图解:


每次做类似的操作都要手动建议StubStudentRepositories存根,着实麻烦。好在Mock框架(Moq)可以自动帮我们完成这个步骤。
例:

[Fact] public void Create_Mock_Ok() { var studentRepositories = new Mock<IStudentRepositories>(); var notiy = new Mock<Notiy>(); StudentService service = new StudentService(studentRepositories.Object); var isCreateOk = service.Create(null); Assert.True(isCreateOk); }

相比上面的示例,是不是简化多了。起码代码看起来清晰了,可以更加注重测试逻辑。


下面接着来看另外的情况,并且已经通过了测试

public class Notiy { public bool Info(string messg) { //发送消息、邮件发送、短信发送。。。 //......... if (string.IsNullOrWhiteSpace(messg)) { return false; } return true; } } public class Notiy_Tests { [Fact] public void Info_Ok() { Notiy notiy = new Notiy(); var isNotiyOk = notiy.Info("消息发送成功"); Assert.True(isNotiyOk); } }

现在我们接着前面的Create方法加入消息发送逻辑。

public bool Create(Student student) { studentRepositories.Add(student); var isNotiyOk = notiy.Info("" + student.Name);//消息通知 //其他一些逻辑 return isNotiyOk; } [Fact] public void Create_Mock_Notiy_Ok() { var studentRepositories = new Mock<IStudentRepositories>(); var notiy = new Mock<Notiy>(); StudentService service = new StudentService(studentRepositories.Object, notiy.Object); var isCreateOk = service.Create(new Student()); Assert.True(isCreateOk); }

而前面我们已经对Notiy进行过测试了,接下来我们不希望在对Notiy进行耗时操作。当然,我们可以通过上面的Mock框架来模拟。这次和上面不同,某些情况我们不需要或不想写对应的接口怎么来模拟?那就使用另外一种方式把要测试的方法virtual。
例:

public virtual bool Info(string messg) { //发送消息、邮件发送、短信发送。。。 //......... if (string.IsNullOrWhiteSpace(messg)) { return false; } return true; }

测试如下

[Fact] public void Create_Mock_Notiy_Ok() { var studentRepositories = new Mock<IStudentRepositories>(); var notiy = new Mock<Notiy>(); notiy.Setup(f => f.Info(It.IsAny<string>())).Returns(true);//【1】 StudentService service = new StudentService(studentRepositories.Object, notiy.Object); var isCreateOk = service.CreateAndNotiy(new Student()); Assert.True(isCreateOk); }

我们发现了标注【1】处的不同,这个代码的意思是,执行模拟的Info方法返回值为true。参数It.IsAny() 是任意字符串的意思。
当然你也可以对不同参数给不同的返回值:

notiy.Setup(f => f.Info("")).Returns(false); notiy.Setup(f => f.Info("消息通知")).Returns(true);

有时候我们还需要对private方法进行测试

  • 使用nuget 安装 MSTest.TestAdapter 1.1.17
  • 使用nuget 安装 MSTest.TestFramework 1.1.17
  • 例:

    private bool XXXInit() { return true; } [Fact] public void XXXInit_Ok() { var studentRepositories = new StudentService(); var obj = new Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject(studentRepositories); Assert.True((bool)obj.Invoke("XXXInit")); }

    如果方法有参数,接着Invoke后面传入即可。

    好了,就说这么多吧。只能说测试的内容还真多,想要一篇文章说完是不可能的。但希望已经带你入门了。

    附录

    xUnit(2.0) 断言 (来源)

    Moq(4.7.10) It参数约束

    相关资料

  • Moq(Mock框架):
  • 相关推荐


  • demo

  • https://github.com/zhaopeiym/BlogDemoCode/tree/master/UnitTestingDemo
  • posted @

     

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • 使用测试用例来约束自己的代码 - 陈宏鸿

      使用测试用例来约束自己的代码 - 陈宏鸿

      2017-05-09 14:00

    • Android -- 带你从源码角度领悟Dagger2入门到放弃(一) - 阿呆哥哥

      Android -- 带你从源码角度领悟Dagger2入门到放弃(一) - 阿呆哥哥

      2017-04-21 11:02

    • 程序员带你一步步分析AI如何玩FlappyBird - yhthu

      程序员带你一步步分析AI如何玩FlappyBird - yhthu

      2017-04-13 09:03

    • 火狐手机测试 - yangzailu1990

      火狐手机测试 - yangzailu1990

      2017-03-14 15:00

    网友点评
    w