c# - Rhino.Mocks : method calls recorder (a. k.a.测试 spy )

标签 c# dependency-injection mocking rhino-mocks

我有一段逻辑要测试,它使用依赖注入(inject)接口(interface)和一个(或多个)void 方法,例如:

interface IMyService
{
    void MethodA (MyComplexObject arg1, int arg2);
}

我想要的是为这个 IMyService 创建一个 stub ,它只会记录 MethodA 的方法调用,我稍后会能够以列表的形式访问它,例如:

MyComplexObject actualParameter = serviceRecorder
    .GetMethodRecordings("MethodA").GetRecord(10).GetInputParameter(0);

我需要它来检查某个调用的此类参数的内容并对其进行断言。我知道还有其他方法可以做到这一点(比如设置带有约束的期望调用),但是当你有很多调用并且你只想在第 51 个调用上进行断言时,这似乎更容易编写。

那么 Rhino.Mocks 中是否有某种机制可以解决这个问题,或者我是否留给自己的设备(编写具有记录功能的虚拟 IMyService 实现)?

注意:(我知道这可能会导致测试变得脆弱,我知道后果)。

更新:这是我目前的发现(部分感谢 Mark 帮助将此模式命名为 Test Spy):

最佳答案

// arrange
var myServiceStub = MockRepository.GenerateStub<IMyService>();
var myComplexObj = new MyComplexObject 
{
    SomeProp = "something",
    SomeOtherProp = "something else"
};

// act
myServiceStub.MethodA(myComplexObj, 10);

// assert
myServiceStub.AssertWasCalled(
    x => x.MethodA(
        Arg<MyComplexObject>.Matches(
            arg1 => arg1.SomeProp == "something" &&
                    arg1.SomeOtherProp == "something else"
        ), 
        Arg<int>.Is.Equal(10)
    )
);

注意:不要忘记将接口(interface)公开,否则 Rhino Mocks 将无法创建代理。


更新:

抱歉,我没有仔细阅读您的问题。以下是获得所需行为的方法:

var args = myServiceStub.GetArgumentsForCallsMadeOn(
    x => x.MethodA(null, default(int)),
    x => x.IgnoreArguments()
);

var theComplexObjectPassedAtThe51thCall = (MyComlexObject)args[50][0];
// TODO: assert something on this object

关于c# - Rhino.Mocks : method calls recorder (a. k.a.测试 spy ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1695830/

相关文章:

unit-testing - 单元测试具有 ORM 交互的 Go 函数

python AttributeError assert_called

c# - 如何正确关闭已创建多个线程的 C# 应用程序?

c# - 在我的C#客户端中接收意外的udp数据包

ios - 如何对 `viewDidLoad()` 进行单元测试

php - 什么时候依赖注入(inject)容器会变得太大,我该怎么办?

c# - 将 char*[] 从 c++ dll 结构传递到 c#

c# - 如何暂停/挂起一个线程然后继续它?

java - 在 Spring 运行时注册 bean(prototype)

python - 如何在 Sphinx 中模拟 wxPython?