c# – 使用Moq在mock对象中定义方法实现

前端之家收集整理的这篇文章主要介绍了c# – 使用Moq在mock对象中定义方法实现前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
情况就是这样.我有异步调用所以我需要为此进行Mid tier才能测试它.
  1. request.BeginGetResponse(new AsyncCallback(LoginCallback),requestState);

因此,为了能够在没有实际请求的情况下测试它,我创建了可以模拟的界面.

  1. public interface IRequestSender
  2. {
  3. void Send(HttpWebRequest request,AsyncCallback internalCallback,object requestState);
  4. }

然后在实现中我可以使用上面的那个调用,我可以提供一些模拟类来调用我的回调方法,无论请求是否有效.我的模拟类看起来像这样.

  1. public class RequestSenderMock : IRequestSender
  2. {
  3. public void Send(HttpWebRequest request,object requestState)
  4. {
  5. var result = new Mock<IAsyncResult>();
  6. result.Setup(x => x.AsyncState).Returns(requestState);
  7. internalCallback(result.Object);
  8. }
  9. }

我现在可以在单元测试中轻松创建模拟对象并使用它.但是当我创造

  1. var sender = new Mock<RequestSenderMock>();

我无法验证此对象的通话计数.

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

它说我的方法需要是虚拟的.
有没有办法在不使我的方法虚拟的情况下做到这一点?如果我能在某种程度上指定使用接口时的方法实现,那将是最好的.

  1. var sender = new Mock<IRequestSender>();

并以某种方式使用Setup方法或其他一些方法在这个模拟对象上进行实现.比我简单地删除我的模拟课程.
这可能吗?你有什么建议?

解决方法

我发现你正在创建一个手动模拟并使用模拟框架来模拟它(模拟模拟),这让我感到困惑.我会考虑将您的自定义函数移动到某个实用程序类中,并使用回调代替.

例:

  1. public class RequestSenderHelpers
  2. {
  3. public static void Send(HttpWebRequest request,object requestState)
  4. {
  5. var result = new Mock<IAsyncResult>();
  6. result.Setup(x => x.AsyncState).Returns(requestState);
  7. internalCallback(result.Object);
  8. }
  9.  
  10. }
  11.  
  12. [Test]
  13. public void Callback_VerifyingWithMethodImplementation_VerifyWorks()
  14. {
  15. // arrange
  16. var sender = new Mock<IRequestSender>();
  17. sender.Setup(s => s.Send(It.IsAny<HttpWebRequest>(),It.IsAny<object>())).Callback<HttpWebRequest,AsyncCallback,object>(RequestSenderHelpers.Send);
  18.  
  19. // act
  20. sender.Object.Send(null,delegate {},null);
  21.  
  22. // assert
  23. sender.Verify(s => s.Send(It.IsAny<HttpWebRequest>(),It.IsAny<object>()));
  24. }

为了避免冗长的设置,您可以在扩展方法中包装方法的设置并相应地更改测试:

  1. public static class RequestSenderHelpers
  2. {
  3. public static void Send(HttpWebRequest request,object requestState)
  4. {
  5. var result = new Mock<IAsyncResult>();
  6. result.Setup(x => x.AsyncState).Returns(requestState);
  7. internalCallback(result.Object);
  8. }
  9.  
  10. public static void SetupSendWithMockedAsyncResult(this Mock<IRequestSender> sender)
  11. {
  12. sender.Setup(s => s.Send(It.IsAny<HttpWebRequest>(),object>(Send);
  13. }
  14.  
  15. }
  16.  
  17. [Test]
  18. public void Callback_VerifyingWithMethodImplementation_VerifyWorks()
  19. {
  20. // arrange
  21. var sender = new Mock<IRequestSender>();
  22. sender.SetupSendWithMockedAsyncResult();
  23.  
  24. // act
  25. sender.Object.Send(null,It.IsAny<object>()));
  26. }

猜你在找的C#相关文章