gpt4 book ai didi

c# - 使用 Moq 在模拟对象中定义方法实现

转载 作者:太空狗 更新时间:2023-10-29 21:14:25 34 4
gpt4 key购买 nike

情况是这样的。我有异步调用,所以我需要为此创建中间层以便能够对其进行测试。

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

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

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<IAsyncResult>();
result.Setup(x => x.AsyncState).Returns(requestState);
internalCallback(result.Object);
}
}

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

var sender = new Mock<RequestSenderMock>();

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

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

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

var sender = new Mock<IRequestSender>();

并且以某种方式使用 Setup 方法或其他方法在这个模拟对象上实现。比我简单地删除我的模拟类(class)。这可能吗?你有什么建议?

最佳答案

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

例子:

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>()));
}

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

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>()));
}

关于c# - 使用 Moq 在模拟对象中定义方法实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6834126/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com