单元测试(C#版)

发表于:2018-5-02 13:10

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:丑小丫大笨蛋    来源:简书

分享:
  3. 单元测试中不得不说的知识点
  (1)断言Assertion
  要验证代码的行为是否与期望一致时,我们需要使用断言来判断某个语句为真或为假,以及某些结果值与期望值是否相等,如IsTrue()、IsFalse()、AreEqual()等。
  Assert.AreEqual(expected, actual [, string message]);
  其中前两个参数很好理解,分别为期望值和实际值,最后一个可选参数是发生错误时报告的消息。如果不提供的话,出错后会看到这样的error message:Assert.AreEqual failed. Expected: xx. Actual: yy.。如果你的那个单元测试函数中有很多Assert.AreEqual的话,你就不清楚究竟是在哪个Assertion出错的,而当你对每个Assertion放上相应的message的话,出错时就可以一眼看出具体出错的Assertion。
  另外,在用断言进行浮点数的比较时还需要提供另外一个参数tolerance。
  有时候每个test里我们都需要进行一系列相同或者类似的断言,那么我们可以尝试编写自定义的断言,这样测试的时候使用这个自定义的断言即可。
  (2)test 组成
  从上面的例子可以看到,test project与普通project的区别就是在class和method上面增加了一个属性。在不同的框架下这些属性还是不一样的,比如说我们上面用到的VS里自带的test框架,使用的是[TestClass]和[TestMethod],而大家最常用的NUint框架则使用的是[TestFixture]和[Test]。
  另外,还有几个attribute在实际项目中我们也会经常用到,那就是[SetUp]、[TearDown]、[TestFixtureSetUp]和[TestFixtureTearDown]。它们用来在调用test之前设置测试环境和在test之后释放资源。前两个是per-method,即每个用[Test]修饰的方法在运行前后都会调用[SetUp]和[TearDown];而后两个则是per-class的,即用于[TestFixture]修饰的类的前后。
  (3)对于异常的测试
  对于预期的异常,只要在测试方法上添加[ExpectedException(typeof(YourExpectedExcetion))]属性即可。但是需要注意的是,一旦这个方法期望的异常抛出了,测试方法中剩余的代码就会被跳过。
  所以NUint里面还有一种方式来验证异常,即Assert.Throws<ExpectedException>(() => methodToTest());,这样就可以在一个test method里面验证多个抛出异常的情况了。
  (4)使用mock对象
  单元测试的目标是一次只验证一个方法或一个类,但是如果这个方法依赖一些其他难以操控的东西,比如网络、数据库等。这时我们就要使用mock对象,使得在运行unit test的时候使用的那些难以操控的东西实际上是我们mock的对象,而我们mock的对象则可以按照我们的意愿返回一些值用于测试。
  比如说,我们在某个函数中需要利用HttpClient通过SendAsync方法从某个EndPoint获取数据进行处理。但是在local测试的时候不一定能够连上那个EndPoint,或者不能保证那个EndPoint会返回什么东西。所以我们可以写mock一个ResponseHandler,这样我们就可以把mock的返回结果放进httpClient中传给需要测试的模块,这样就可以测试该模块内后续部分的处理了。
  internal class MockResponseHandler : DelegatingHandler
  {
      public HttpStatusCode StatusCode { get; set; }
      public HttpContent Content { get; set; }
      protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
                  System.Threading.CancellationToken cancellationToken)
      {
          return await ReturnRespsonse();
      }
      private Task<HttpResponseMessage> ReturnRespsonse()
      {
          var response = new HttpResponseMessage()
          {
              StatusCode = this.StatusCode,
              Content = this.Content
          };
          return Task.Run(() => response);
      }
  }```
  var successHttpClient = new HttpClient(
  new MockResponseHandler
  {
  StatusCode = HttpStatusCode.OK
  });
  var forbidHttpClient = new HttpClient(
  new MockResponseHandler
  {
  StatusCode = HttpStatusCode.Forbidden,
  Content = new StringContent(testError)
  });
  实际上,`.NET`中现在很多mock对象的框架供选择(参见http://www.mockobjects.org ),很多常用的mock都可以直接使用框架,而不需要自己去写。
  ####4. 帮助你更好地进行单元测试的工具
  [NUnit](http://www.nunit.org/index.php?p=download)
  [ReShaper](https://resharper-support.jetbrains.com/hc/en-us/articles/207242355-Where-can-I-download-an-old-previous-ReSharper-version-)
  奈何家里的笔记本下载它们一直失败,所以这里先给个链接,以后有机会再介绍一下它们吧(⊙﹏⊙)b

22/2<12
精选软件测试好文,快来阅读吧~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号