最好的接口模拟/假的部分实现

问题描述:

在C#下有一个很好的工具,假部分测试实现复杂的接口(服务,存储库等)?最好的接口模拟/假的部分实现

我目前使用的模拟框架(RhinoMocks)太慢,太难以处理这个目的。

先决条件:

  • 没有显著的性能损失,相比于真正的实现(批量测试)
  • 实现与基本的逻辑和数据(例如:字典,而不是数据库表)
  • 无需更换测试,当界面改变时。

全面推行例如:

public interface IMyInterface 
{ 
    int PropertyA { get; set; } 
    int PropertyB { get; set; } 
    void DoSomethingWithX(int x); 
    int GetValueOfY(); 
} 

public class FakeImplementation : IMyInterface 
{ 
    private int _valueOfYCalls = 0; 

    public int PropertyA { get; set; } 
    public int PropertyB { get; set; } 
    public void DoSomethingWithX(int x) 
    { } 

    public int GetValueOfY() 
    { 
     return _valueOfYCalls++; 
    } 
} 

计数器只是模拟了基本的逻辑。

问题是,如果接口得到一个新的方法,如SetSomeZ(int z),测试将不会建立/运行了,没有明确的改变。

有没有一个假的/模拟的框架,使用基本的实现,但通过虚拟/覆盖或包装自动添加成员?

像这样的:

[ImplementsInterface(nameof(IMyInterface))] 
public class FakeImplementationBase 
{ 
    private int _valueOfYCalls = 0; 

    [ImplementsMember(nameof(IMyInterface.GetValueOfY))] 
    public virtual int GetValueOfY() 
    { 
     return _valueOfYCalls++; 
    } 
} 

工具/框架应​​在运行时生成全面实现类型,类似于嘲笑/存根,但使用的基本实现,只需添加缺少的接口部分。

这不应该是真正的单元测试,而是为了更复杂的目的。它也是具有丰富接口和类的传统软件,并不太多关于“单一责任”。

Moq正是你想要的。

public interface IFoo { 
    int MethodA(int a); 
    void MethodB(long b); 
    void MethodC(string c); 
    ... 
} 

var MoqFoo = new Mock<IFoo>(); 
MoqFoo.Setup(m => m.MethodA(It.Is(a => a > 0)).Returns<int>(a => a + 1); 
MoqFoo.Setup(m => m.MethodC(It.IsAny<string>()).Callback<string>(c => Debug.Write(c)); 

请注意我们怎么没有为MethodB做.Setup()?当你声明它时,所有的方法和属性都会得到虚拟方法/属性,.Setup()将会指定你自己定制的方法和属性。所以如果你的接口有10个方法,但你只想测试MethodD(),你只需要为它编写代码。

http://www.developerhandbook.com/unit-testing/writing-unit-tests-with-nunit-and-moq/

+0

谢谢,Moq的表现如何? RhinoMocks有类似的语法,但比实际的类慢得多(只要它们只在内存中)。我想避免RhinoMocks中'.Setup(...)'或'.Stub()'的相当复杂的语法。我期望框架在运行时创建一个新类型,它像一个普通类一样实例化,只进行一次反射,然后像编码类那样执行性能。 –