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

情况就是这样。 我有异步调用所以我需要为此进行Mid tier才能测试它。

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

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

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

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

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

我现在可以在unit testing中轻松创建模拟对象并使用它。 但是当我创造

 var sender = new Mock(); 

我无法validation此对象的通话计数。

 sender.Verify(x => x.Send(It.IsAny(), It.IsAny(), It.IsAny()), Times.Once()); 

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

 var sender = new Mock(); 

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

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

例:

 public class RequestSenderHelpers { public static void Send(HttpWebRequest request, AsyncCallback internalCallback, object requestState) { var result = new Mock(); result.Setup(x => x.AsyncState).Returns(requestState); internalCallback(result.Object); } } [Test] public void Callback_VerifyingWithMethodImplementation_VerifyWorks() { // arrange var sender = new Mock(); sender.Setup(s => s.Send(It.IsAny(), It.IsAny(), It.IsAny())).Callback(RequestSenderHelpers.Send); // act sender.Object.Send(null, delegate {}, null); // assert sender.Verify(s => s.Send(It.IsAny(), It.IsAny(), It.IsAny())); } 

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

 public static class RequestSenderHelpers { public static void Send(HttpWebRequest request, AsyncCallback internalCallback, object requestState) { var result = new Mock(); result.Setup(x => x.AsyncState).Returns(requestState); internalCallback(result.Object); } public static void SetupSendWithMockedAsyncResult(this Mock sender) { sender.Setup(s => s.Send(It.IsAny(), It.IsAny(), It.IsAny())).Callback(Send); } } [Test] public void Callback_VerifyingWithMethodImplementation_VerifyWorks() { // arrange var sender = new Mock(); sender.SetupSendWithMockedAsyncResult(); // act sender.Object.Send(null, delegate {}, null); // assert sender.Verify(s => s.Send(It.IsAny(), It.IsAny(), It.IsAny())); }