c# - 使用 Rhino.Mocks 检查传递给委托(delegate)的预期值

标签 c# unit-testing lambda assert rhino-mocks

我正在尝试编写一个测试用例,该用例将确认传递给被测方法的参数值用于调用委托(delegate)函数,该委托(delegate)函数作为参数传递给模拟服务上的方法。下面的例子说明了我在做什么:

被测方法:

public IList<IResultData> GetResultData(int id)
{
    Func<IExternalInterface, List<ExternalData> getDataMethod = client => client.GetExternalData(id);     
    List<ExternalData> externalDataList = serviceClient.ExecuteService(getDataMethod, "GetExternalData"); 

    var result = new List<ResultData>();

    //Some code to convert externalDataList into an IList<IResultData>

    return result;
}

测试方法:

[TestMethod]
public void TestMethodCall()
{
    var mockServiceClient = MockRepository.GenerateMock<IServiceClient>();
    mockServiceClient.Expect(x => x.ExecuteService(
            Arg<Func<IExternalInterface, List<ExternalData>>.Is.NotNull,
            Arg<string>.Is.Equal("GetExternalData")));

    var myClass = new MyClass(mockServiceClient);

    var result = myClass.GetResultData(3);

    //Some assertions that result is as expected.
}

有没有办法断言传递给 Execute 方法的函数是从测试方法调用 GetResultData() 传递的 id 3?被模拟的服务在一个不受我控制的库中,所以我无法更改它的签名。

最佳答案

以下模式将允许您断言 lambda:

[TestMethod]
public void TestMethod1()
{
    var wasCalled = false;

    var fakeService = MockRepository.GenerateStub<IExternalInterface>();

    fakeService.Stub(x => x.GetExternalData(1))
               .Return(new List<ExternalData>() {new ExternalData() {Id = 1}});

    fakeService.Stub(service => service.ExecuteService(Arg<Func<IExternalInterface, 
                     List<ExternalData>>>.Is.Anything, Arg<string>.Is.Anything))
               .WhenCalled(invocation =>
               {
                   wasCalled = true;
                   var func = (Func<IExternalInterface, List<ExternalData>>) invocation.Arguments[0];
                   var res = func(fakeService);

                   //
                   // Assert here the "res"
                   //


               }).Return(null);

    var target = new MyClass(fakeService);

    target.GetResultData(1);

    Assert. IsTrue(wasCalled);
}

但是,根据您提供的代码,更好的解决方案是使用 Do 方法,如下所示:

[TestMethod]
public void TestMethod1()
{
    var fakeService = MockRepository.GenerateStub<IExternalInterface>();

    fakeService.Stub(x => x.GetExternalData(1)).Return(new List<ExternalData>() {new ExternalData() {Id = 1}});

    fakeService.Stub(service => service.ExecuteService(Arg<Func<IExternalInterface, 
                                                       List<ExternalData>>>.Is.Anything, Arg<string>.Is.Anything))
               .Do(new Func<Func<IExternalInterface, List<ExternalData>>, string, List<ExternalData>>((func, str)=>func(fakeService)));

    var target = new MyClass(fakeService);

    var result = target.GetResultData(1);

    //
    // Assert here the "result"
    //

}

关于c# - 使用 Rhino.Mocks 检查传递给委托(delegate)的预期值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39028298/

相关文章:

c# - 将 `DefaultValue` 应用于序列化中的每个字符串属性

c# - 具有向后导航的流畅接口(interface)(方法链接)

unit-testing - 复杂对象上的最佳实践 TDD

c# - IQueryable 上的动态 "WHERE IN"(linq to SQL)

c++ - (C++14) lambda 数组 : error: 'name' declared as array of 'auto'

c# - Unity Particle Collider 与粒子

c# - 以编程方式滚动带有计时器的 ScrollViewer 变得不稳定

python - 模拟内置函数在导入模块中打开

c++ - 如何为 C++ 项目编写测试(不使用框架)

c# - 如何在 linq 查询中传递表达式列表