最佳界面模拟/假部分实现

时间:2017-09-27 12:05:00

标签: c# mocking integration-testing partial

在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++;
    }
}

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

这不应该用于实际的单元测试,而是用于更复杂的目的。它也是具有巨大接口和类的遗留软件,并没有太多关于单一责任的问题"。

1 个答案:

答案 0 :(得分:0)

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/