首页 > 解决方案 > Polly 策略在调用 Execute() 时抛出异常

问题描述

我在我的一个项目中使用了一个稍微过时的 Polly 版本 - 5.9

对于测试用例,我正在尝试创建一个在Execute()调用它时总是会抛出异常的策略。该策略将在测试时注入到实际代码中,并且预期它会失败。

我可以做类似的事情:

Policy somePolicy = Policy.Handle<Exception>().Retry();
somePolicy.Execute((cToken) => { throw new Exception(); }, new Context("A context"), cancellationToken); 

但是,我无法访问或控制 的第一个参数Execute(),即(cToken) => { throw new Exception(); }零件。

我还尝试了一种解决方法HandleResult(),如下所示:

Policy<bool> somePolicy = Policy.HandleResult<bool>((o) => { throw new Exception(); }).Retry();

但是,这很有效,这Policy<bool>使得与仅使用Policy.

策略本身并不重要,只要它在任何调用Execute(). 有没有一种干净的方法来实现这一目标?

PS:目前升级 Polly 不是一个选项。

标签: c#polly

解决方案


两种选择:

1 使用西米

Simmy是一个为注入故障提供 Polly 策略的项目。

例如,您可以定义:

var faultPolicy = MonkeyPolicy.InjectFault(new FooException());

(以及许多其他更强大的变体)。

但是,这仅与 Polly v7+ 兼容。

2 使用策略接口和模拟策略

Polly 策略都实现了执行接口。根据政策:

  • ISyncPolicy
  • ISyncPolicy<TResult>
  • IAsyncPolicy
  • IAsyncPolicy<TResult>

这些接口定义了.Execute/Async()策略上可用的重载。

有了这些,您可以使用标准的依赖注入和模拟技术来构建测试:

  • 在您的生产代码中,按执行接口类型声明和使用策略。
  • 确保将ISyncPolicyor 类似(或 a PolicyRegistry)注入到被测系统中,而不是在其中创建,以便测试可以替代模拟。
  • 在单元测试中,改为传入Mock<ISyncPolicy>. 然后,您可以使用 Moq 等任何模拟工具.Execute()通过策略模拟调用以引发异常。

例如:

ISyncPolicy mockPolicy = new Mock<ISyncPolicy>();
mockPolicy.Setup(p => p.Execute(It.IsAny<Func<Bar>>())
    .Throws(new FooException());

Polly wiki on unit-testing中更详细地介绍了这一点以及更多内容,并附有代码示例。


推荐阅读