zoukankan      html  css  js  c++  java
  • NSubstitute完全手册1

    NSubstitute完全手册(一)入门基础

    NSubstitute入门

    最简单的入门方式就是创建一个测试项目,并将 NSubstitute 引用到其中。可以通过 NuGet 或 OpenWrap 来获取 NSubstitute 包。也可以直接下载 NSubstitute 文件,然后将 NSubstitute.dll 引用到项目中。

    然后就可以创建一个新的测试 Fixture(可以选择使用你最喜欢的UT测试框架,本文涉及的示例中我们使用MSTest),开始思考从哪里入手。

    首先,添加 using NSubstitute; 到当前的C#代码文件中,有了它我们就可以开始创建替身了。

    现在,比如我们有一个非常简单的计算器接口:

    1     public interface ICalculator
    2     {
    3       int Add(int a, int b);
    4       string Mode { get; set; }
    5       event EventHandler PoweringUp;
    6     }

    我们可以让NSubstitute来创建类型实例的替代实例。可以创建诸如 Stub、Mock、Fake、Spy、Test Double 等,但当我们只是想要一个能有一定程度控制的替代实例时,为什么我们要困扰于此呢?

    1     [TestMethod]
    2     public void Test_GetStarted_GetSubstitute()
    3     {
    4       ICalculator calculator = Substitute.For<ICalculator>();
    5     }

    现在,我们可以告诉被创建的替代实例,当方法被调用时返回一个值:

    复制代码
    1     [TestMethod]
    2     public void Test_GetStarted_ReturnSpecifiedValue()
    3     {
    4       ICalculator calculator = Substitute.For<ICalculator>();
    5       calculator.Add(1, 2).Returns(3);
    6 
    7       int actual = calculator.Add(1, 2);
    8       Assert.AreEqual<int>(3, actual);
    9     }
    复制代码

    我们可以检查该替代实例是否接收到了一个指定的调用,或者未收到某指定调用:

    复制代码
    1     [TestMethod]
    2     public void Test_GetStarted_ReceivedSpecificCall()
    3     {
    4       ICalculator calculator = Substitute.For<ICalculator>();
    5       calculator.Add(1, 2);
    6 
    7       calculator.Received().Add(1, 2);
    8       calculator.DidNotReceive().Add(5, 7);
    9     }
    复制代码

    如果 Received() 断言失败,NSubstitute 会尝试给出有可能是什么问题:

    复制代码
    1     [TestMethod]
    2     [ExpectedException(typeof(ReceivedCallsException))]
    3     public void Test_GetStarted_DidNotReceivedSpecificCall()
    4     {
    5       ICalculator calculator = Substitute.For<ICalculator>();
    6       calculator.Add(5, 7);
    7 
    8       calculator.Received().Add(1, 2);
    9     }
    复制代码
    Expected to receive a call matching:
        Add(1, 2)
    Actually received no matching calls.
    Received 1 non-matching call (non-matching arguments indicated with '*' characters):
        Add(*5*, *7*)

    我们也可以对属性使用与方法类似的 Retures() 语法,或者继续使用简单的属性 setter 来设置返回值。

    复制代码
     1     [TestMethod]
     2     public void Test_GetStarted_SetPropertyValue()
     3     {
     4       ICalculator calculator = Substitute.For<ICalculator>();
     5 
     6       calculator.Mode.Returns("DEC");
     7       Assert.AreEqual<string>("DEC", calculator.Mode);
     8 
     9       calculator.Mode = "HEX";
    10       Assert.AreEqual<string>("HEX", calculator.Mode);
    11     }
    复制代码

    NSubstitute 支持参数匹配功能,可以设置参数规则,并断言判断是否接收到参数匹配的调用。

    复制代码
     1     [TestMethod]
     2     public void Test_GetStarted_MatchArguments()
     3     {
     4       ICalculator calculator = Substitute.For<ICalculator>();
     5 
     6       calculator.Add(10, -5);
     7 
     8       calculator.Received().Add(10, Arg.Any<int>());
     9       calculator.Received().Add(10, Arg.Is<int>(x => x < 0));
    10     }
    复制代码

    我们也可以在使用参数匹配功能的同时,传递一个函数给 Returns() ,以此来使替代实例具有更多的功能。

    复制代码
     1     [TestMethod]
     2     public void Test_GetStarted_PassFuncToReturns()
     3     {
     4       ICalculator calculator = Substitute.For<ICalculator>();
     5       calculator
     6          .Add(Arg.Any<int>(), Arg.Any<int>())
     7          .Returns(x => (int)x[0] + (int)x[1]);
     8 
     9       int actual = calculator.Add(5, 10);
    10 
    11       Assert.AreEqual<int>(15, actual);
    12     }
    复制代码

    Returns() 也可通过构造一个返回值序列来指定多个参数。

    复制代码
     1     [TestMethod]
     2     public void Test_GetStarted_MultipleValues()
     3     {
     4       ICalculator calculator = Substitute.For<ICalculator>();
     5       calculator.Mode.Returns("HEX", "DEC", "BIN");
     6 
     7       Assert.AreEqual<string>("HEX", calculator.Mode);
     8       Assert.AreEqual<string>("DEC", calculator.Mode);
     9       Assert.AreEqual<string>("BIN", calculator.Mode);
    10     }
    复制代码

    最后,我们可以在替代实例上引发事件通知:

    复制代码
     1     [TestMethod]
     2     public void Test_GetStarted_RaiseEvents()
     3     {
     4       ICalculator calculator = Substitute.For<ICalculator>();
     5       bool eventWasRaised = false;
     6 
     7       calculator.PoweringUp += (sender, args) =>
     8       {
     9         eventWasRaised = true;
    10       };
    11 
    12       calculator.PoweringUp += Raise.Event();
    13 
    14       Assert.IsTrue(eventWasRaised);
    15     }
    复制代码

    基本上这些就是入门 NSubstitute 的全部内容。对于更详细的功能说明,以及一些 NSubstitute 所支持的不太常用的需求,请继续阅读。

     
     
     
    标签: C#.NETUnit TestingUTNSubstituteStubMockTest Double

    STSdb,最强纯C#开源NoSQL和虚拟文件系统

    回顾

    几个月前写了一篇文章,关于 C#写的NoSQL开源项目/系统(系列),看过该文章的同学,估计会对.NET能实现高效的NoSQL是有信心的。几个月过去了,有了新进展。

    STSdb是什么

    再来说明一下STSdb是什么:STSdb是C#写的开源数据库和虚拟文件系统,支持实时索引,性能是同类产品的几倍到几十倍,访问官方网站

    特性

    • 支持几十亿级别的数据存取
    • 支持TB级别文件大小
    • 实时索引
    • 内置压缩
    • 内置序列化
    • 支持稀疏分散的文件(byte[])

    为什么?

    数据库的共同点

    每个数据库都有一个共同点,就是受限于索引结构,因此每当改进了索引数据结构,性能也随之大增。

    性能瓶颈

    在数据库系统中,每当对数据进行索引,数据的逻辑位置会被映射到物理设备,这个映射严重依赖设备的寻址时间。

    解决办法

    当遇到性能瓶颈时:

    办法就是,不对每个操作都进行一次寻址,而是每次寻址都做多个操作。

    解决方案-WATERFALLTREE™ (瀑布树)

    STSdb 4.0突破性地发现并实现了Waterfall-tree (瀑布树)树结构。Waterfall-tree是注册商标,并且拥有专利。与传统的B+树类似,但B+树是同步操作,而瀑布树是分组异步操作。

    现有的解决方案有一个共同的缺点:当索引随机主键的时候,I/O性能不高(退化严重)。

    而STSdb4.0的瀑布树带了来前所未有的性能提升。

    下图直观地展示了瀑布树的原理:

    性能比较

    数据库存储设计
    Amazon Dynamo DB Zero-Hop Distributed Hash Table
    Cassandra Memtable / SSTable
    Couch DB Append-only B-tree
    Db4objects B-tree
    Google Big Table SSTable (log-structured storage)
    H base Memtable / SSTable on HDFS
    Level DB LSM-tree
    Memcached Memory caching
    Mongo DB B-tree
    Oracle Berkeley DB B+-tree
    Perst B-tree/T-tree/R-tree/Patricia trie/KD-tree
    Redis In-memory only with background snapshots
    Scalaris In-memory only
    Tokyo Cabinet Hash or B-tree

    随机写

    随机读

    顺序写

    顺序读

    这个性能,只能用凶残来形容啊!

    应用领域

    Hello STSdb

    打开数据库并写入数据

    using (StorageEngine engine = new StorageEngine("stsdb4.sys", "stsdb4.dat"))
    {
        XIndex<int, string> table = engine.OpenXIndex<int, string>("table");
      
        for (int i = 0; i < 1000000; i++)
        {
            table[i] = i.ToString();
        }
      
        table.Flush();
        engine.Commit();
    }

    读取数据

    using (StorageEngine engine = new StorageEngine("stsdb4.sys", "stsdb4.dat"))
    {
        XIndex<int, string> table = engine.OpenXIndex<int, string>("table");
      
        foreach (var row in table) //table.Forward(), table.Backward()
        {
            Console.WriteLine("{0} {1}", row.Key, row.Value);
        }
    }

    更多例子

    可以访问这里查看更多的例子,或者下载类库或代码,里面有pdf文档。

     
     
    标签: stsdb
  • 相关阅读:
    杂谈
    xss bypass 学习记录
    小结--dns注入
    在CentOS 7 安装没有mysql
    备份WordPress
    php留言
    基于mysq搭建的l许愿墙
    http服务的安装与配置
    centos 7忘记密码重置
    安装centos 7 桌面
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3091760.html
Copyright © 2011-2022 走看看