【问题标题】:Rhinomocks - Mocking delegatesRhinomocks - 模拟代表
【发布时间】:2011-04-13 14:22:54
【问题描述】:
public interface IServiceInvoker
{  
    R InvokeService<T, R>(Func<T, R> invokeHandler) where T : class;
}

public class MediaController : Controller
{ 
    private IServiceInvoker _serviceInvoker;
    public MediaController(IServiceInvoker serviceInvoker)
    {
        _serviceInvoker = serviceInvoker;
    }

    public JsonResult GetAllMedia()
    {
        var media = _serviceInvoker.InvokeService<IMediaService, List<MediaBase>>(proxy    => proxy.GetAllMediaInJson());

        JsonResult jsonResult = new JsonResult();
        jsonResult.Data = media;
        jsonResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
        return jsonResult;

}


[TestClass]
public class MediaControllerTests
{
    [TestMethod]
    public void GetAllMedia()
    {
        JsonResult data;
        var serviceInvoker = MockRepository.GenerateStub<IServiceInvoker>();
        var media = CreateSeveralMedia();
        serviceInvoker.Stub(c => c.InvokeService<IMediaService, List<MediaBase>>(p => p.GetAllMediaInJson())).Return(media);
        data = new MediaController(serviceInvoker).GetAllMedia();
        serviceInvoker.VerifyAllExpectations();
        Assert.IsNotNull(data);
    }

}

我正在对服务进行存根并返回一个集合。当我运行此测试时,媒体为空。任何想法,我怎样才能对这个模拟设定期望?

【问题讨论】:

    标签: c# rhino-mocks rhino-mocks-3.5


    【解决方案1】:

    刚刚找到解决方案。它似乎有点难看,但它是第一次迭代,可能很快就会出现更优雅的版本。这个想法是创建另一个存根并匹配 Func&lt;&gt; 反对它: 我将为我的用例提供代码:

    [Theory]
    [InlineData(342, 31129, 3456)]
    public void should_call_service_invoker_and_return_result(int number1, int number2, int expected)
    {
        var calculator = MockRepository.GenerateStub<ICalculator>();
        calculator.Stub(_ => _.Add(number1, number2)).Return(expected);
        var serviceInvoker = MockRepository.GenerateStub<ServiceInvoker<ICalculator>>();
        serviceInvoker
            .Stub(_ => _.Invoke(Arg<Func<ICalculator, int>>.Matches(d => d(calculator) == calculator.Add(number1, number2))))
            .Return(expected);
        var serviceConsumer = new ServiceConsumer(serviceInvoker);
    
        var actual = serviceConsumer.GetAddResultFor(number1, number2);
    
        Assert.Equal(expected, actual);
    }
    

    xUnit + 扩展被用作测试框架。请忽略TheoryInlineData 的东西——这只是摆脱不必要的测试设置的另一种方法。

    这是SUT的代码:

    public class ServiceConsumer
    {
        private readonly ServiceInvoker<ICalculator> serviceInvoker;
    
        public ServiceConsumer(ServiceInvoker<ICalculator> serviceInvoker)
        {
            this.serviceInvoker = serviceInvoker;
        }
    
        public int GetAddResultFor(int number1, int number2)
        {
            return serviceInvoker.Invoke(_ => _.Add(number1, number2));
        }
    }
    
    public class ServiceInvoker<T>
    {
        public virtual R Invoke<R>(Func<T, R> func)
        {
            throw new NotImplementedException();
        }
    }
    
    public interface ICalculator
    {
        int Add(int number1, int number2);
    }
    

    希望这会有所帮助。欢迎任何关于如何增加美丽的建议:)

    【讨论】:

      【解决方案2】:

      单元测试中的 lambda 编译为类级方法(单元测试中的方法)。在你的控制器内部,一个不同的 lambda 编译成一个类级别的方法(在控制器内部)。单元测试中设置的存根与控制器中正在执行的存根不匹配,因此 Rhino Mocks 返回默认值 (null)。更多内容:http://groups.google.com/group/rhinomocks/browse_frm/thread/a33b165c16fc48ee?tvc=1

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-31
        相关资源
        最近更新 更多