本文介绍了定义方法实现使用起订量mock对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是这种情况。我异步调用,所以我需要让中间层为这个为了能够测试它。

This is the situation. I had async call so I needed to make Mid tier for this in order to be able to test it.

request.BeginGetResponse(new AsyncCallback(LoginCallback), requestState);



所以,为了能够测试这种没有真正的要求,我创建的接口,我可以嘲笑

So, in order to be able to test this without real request, I created interface which I can mock.

public interface IRequestSender
    {
        void Send(HttpWebRequest request, AsyncCallback internalCallback, object requestState);
    }



然后执行,我可以使用上面调用了象之一,我可以提供一些模拟类调用我的回调方法不论是何种请求是否有效。我的模拟类看起来像这样

Then in implementation I can use call like that one above and I can provide some mock class to call my callback method regardless request is valid or not. My mock class looks like this.

public class RequestSenderMock : IRequestSender
    {
        public void Send(HttpWebRequest request, AsyncCallback internalCallback, object requestState)
        {
            var result = new Mock<IAsyncResult>();
            result.Setup(x => x.AsyncState).Returns(requestState);
            internalCallback(result.Object);
        }
    }



我现在可以很容易地在我的单元测试创​​建模拟对象和使用它。但是,当我创建

I can now easily create mock object in my unit test and use it. But when I create

var sender = new Mock<RequestSenderMock>();



我无法验证此对象的调用次数。

I'm unable to verify call count for this object.

sender.Verify(x => x.Send(It.IsAny<HttpWebRequest>(), It.IsAny<AsyncCallback>(), It.IsAny<object>()), Times.Once());



它说,我的方法必须是虚拟的。
是有办法做到这一点没有让我的方法虚? ,这将是最好的,如果使用接口时,我能以某种方式指定方法impelementation

It says that my method needs to be virtual.Is there a way to do this without making my method virtual? It would be best if I could somehow specify method impelementation when using interface.

var sender = new Mock<IRequestSender>();

和以某种方式与安装方法或其他一些使这个模拟对象实施。比我会简单地删除我的模拟类。
是这可能吗?你有什么建议?

And that somehow with Setup method or some other to make implementation on this mock object. Than I'll simply remove my mock class.Is this possible? What do you suggest?

推荐答案

我觉得很困惑,你正在创建一个人工模拟,并用讽刺的框架,嘲笑它(嘲讽一个模拟)。我会考虑将您的自定义功能集成到一些实用工具类,并使用回调而不是

I find it confusing that you are creating a manual mock and using a mocking-framework to mock it (mocking a mock). I would consider moving your custom functions into some utility class and using callbacks instead.

例如:

public class RequestSenderHelpers
{
    public static void Send(HttpWebRequest request, AsyncCallback internalCallback, object requestState)
    {
        var result = new Mock<IAsyncResult>();
        result.Setup(x => x.AsyncState).Returns(requestState);
        internalCallback(result.Object);
    }

}

    [Test]
    public void Callback_VerifyingWithMethodImplementation_VerifyWorks()
    {
        // arrange
        var sender = new Mock<IRequestSender>();
        sender.Setup(s => s.Send(It.IsAny<HttpWebRequest>(), It.IsAny<AsyncCallback>(), It.IsAny<object>())).Callback<HttpWebRequest, AsyncCallback, object>(RequestSenderHelpers.Send);

        // act
        sender.Object.Send(null, delegate {}, null);

        // assert
        sender.Verify(s => s.Send(It.IsAny<HttpWebRequest>(), It.IsAny<AsyncCallback>(), It.IsAny<object>()));
    }

要避免冗长的设置,你可以包装方法的设置在扩展方法并相应地改变你的测试:

To avoid the verbose setup you can wrap the setup of the method in an extension method and change your test accordingly:

public static class RequestSenderHelpers
{
    public static void Send(HttpWebRequest request, AsyncCallback internalCallback, object requestState)
    {
        var result = new Mock<IAsyncResult>();
        result.Setup(x => x.AsyncState).Returns(requestState);
        internalCallback(result.Object);
    }

    public static void SetupSendWithMockedAsyncResult(this Mock<IRequestSender> sender)
    {
        sender.Setup(s => s.Send(It.IsAny<HttpWebRequest>(), It.IsAny<AsyncCallback>(), It.IsAny<object>())).Callback<HttpWebRequest, AsyncCallback, object>(Send);            
    }

}

    [Test]
    public void Callback_VerifyingWithMethodImplementation_VerifyWorks()
    {
        // arrange
        var sender = new Mock<IRequestSender>();
        sender.SetupSendWithMockedAsyncResult();

        // act
        sender.Object.Send(null, delegate {}, null);

        // assert
        sender.Verify(s => s.Send(It.IsAny<HttpWebRequest>(), It.IsAny<AsyncCallback>(), It.IsAny<object>()));
    }

这篇关于定义方法实现使用起订量mock对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-28 12:44