如何使用CancellationToken作为参数来模拟方法?

时间:2019-04-02 20:02:32

标签: c# moq cancellation-token polly

我最近正在学习并使用Polly为我的代码添加弹性,尤其是对于超时和重试策略。但是,我不知道如何使用Polly对代码进行单元测试。更具体地说,我不知道如何模拟以Cancellation 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();

}

2 个答案:

答案 0 :(得分:0)

您的代码片段永远不会调用此方法“ c.TryCallThirdParty”。

您是否尝试使用Task.Delay(Timespan.FromSeconds(1))而不是Thread.Sleep?每次使用Task.Delay而不是Thread.Sleep都会更好。

答案 1 :(得分:0)

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

但是,要回答“取消fullURL = file.pdf.url client = storage.Client() bucket = client.get_bucket('name-of-my-bucket') blob = bucket.blob(file.pdf.name[:-4] + '/') blob.upload_from_string('', content_type='application/x-www-form-urlencoded;charset=UTF-8') pages = convert_from_path(fullURL, 400) for i,page in enumerate(pages): blob = bucket.blob(file.pdf.name[:-4] + '/' + str(i) + '.jpg') blob.upload_from_string('', content_type='image/jpeg') outfile = file.pdf.name[:-4] + '/' + str(i) + '.jpg' page.save(outfile) of = open(outfile, 'rb') blob.upload_from_file(of) 时如何使Mock<T>引发异常”这一问题: 使用CancellationToken重载。为了清楚起见,我将Returns<TParam1, ...>(Func<TResult, TParam1>)替换为AsyncTimeoutPolicy

CancellationTokenSource