好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

NSubstitute完全手册1

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# ,  .NET ,  Unit Testing ,  UT ,  NSubstitute ,  Stub ,  Mock ,  Test 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文档。

 

 

分类:  1.每日一得 ,  3.开源项目

标签:  stsdb

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于NSubstitute完全手册1的详细内容...

  阅读:59次