gpt4 book ai didi

c# - 如何使用 CancellationToken 作为参数传递来模拟方法?

转载 作者:行者123 更新时间:2023-12-01 21:48:20 26 4
gpt4 key购买 nike

我最近正在学习和使用 Polly 来增强我的代码的弹性,特别是超时和重试策略。但是,我不知道如何使用 polly 对代码进行单元测试。更具体地说,我不知道如何模拟以取消 token 作为参数的方法。下面是我的代码结构

public class Caller
{
private IHttpManager httpManager;
private IAsyncPolicy<HttpResponseMessage> policyWrap;

public Caller(IHttpManager httpManager, IAsyncPolicy<HttpResponseMessage> policyWrap)
{
this.httpManager= httpManager;
this.policyWrap = policyWrap;
}

public async Task CallThirdParty()
{
HttpResponseMessage httpResponse = await policyWrap.ExecuteAsync(async ct => await httpManager.TryCallThirdParty(ct), CancellationToken.None);
}
}

public interface IHttpManager
{
Task<HttpResponseMessage> TryCallThirdParty(CancellationToken cancellationToken);
}

下面是我打算运行但不知道如何运行的单元测试。

[Test]
public void TestBehaviourUnderTimeoutPolicy()
{
// Set up the timeout policy such that the governed delegate will terminate after 1 sec if no response returned
AsyncTimeoutPolicy<HttpResponseMessage> timeoutPolicy = Policy.TimeoutAsync<HttpResponseMessage>(1, TimeoutStrategy.Optimistic);

// mock IHttpManager
var mockHttpManager= new Mock<IHttpManager>();

// THIS IS WHERE I'M HAVING TROUBLE WITH.
// I want to simulate the behaviour of the method such that
// it will throw an exception whenever the CancellationToken passed from the polly caller expires
// But how can I do that with mock?
mockHttpManager.Setup(m => m.TryCallThirdParty(It.IsAny<CancellationToken>()))).Returns(Task.Run(() => { Thread.Sleep(10000); return new HttpResponseMessage(); }));

Caller c = new Caller(mockHttpManager.Object, timeoutPolicy);
await c.CallThirdParty();
}

最佳答案

@Noremac 是对的(您在一个单元测试中测试 2 个元素)。

但是,要回答“如何在 Mock<T> 被取消时使 CancellationToken 抛出异常”的问题:使用Returns<TParam1, ...>(Func<TResult, TParam1>)重载。我替换了AsyncTimeoutPolicyCancellationTokenSource为了清楚起见。

// This test will perma-hang if the exception is not thrown
[TestMethod]
[ExpectedException(typeof(OperationCanceledException))]
public async Task TestMethod1()
{
var source = new Mock<IHttpManager>();
source.Setup(s => s.TryCallThirdParty(It.IsAny<CancellationToken>())).Returns<CancellationToken>(
async token =>
{
// Wait until the token is cancelled
await Task.Delay(Timeout.Infinite, token);
});

var tcs = new CancellationTokenSource(1000);
await new Caller().Get(source.Object, tcs.Token);
}

关于c# - 如何使用 CancellationToken 作为参数传递来模拟方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55482702/

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