我有这样的代码(我必须测试一个存储库,您将看到下面的代码)
public class SomeClass
{
public AsyncPolicyWrap PropName { get; }
public SomeClass(...)
{
PropName = Policy.WrapAsync(someRetry,someCircuitBreaker)
// here there are passed some methods that return someRetry - AsyncRetryPolicy
// and someCircuitBreaker - AsyncCircuitBreakerPolicy
}
}
然后我有另一个 repo 类
public class SomeRepo : ISomeRepo
{
private readonly AsyncPolicy _somePolicy;
public SomeRepo(..., SomeClass someClass) : base(...)
{
_somePolicy = someClass.PropName;
}
public async Task<Result<SomeDTO>> GetDTO(Guid someId)
{
var someResponse = await _somePolicy.ExecuteAsync(() =>
HttpClient.GetAsync(serviceName, $"endpointUrl"));
...
}
}
上面的两段代码无法更改,因为它们是在产品中,而我作为初级开发人员只需要在可能的情况下通过测试来覆盖代码
我尝试编写这样的测试
[TestMethod]
public async Task DoStuff()
{
var repository = DefaultSome();
var result = await repository.GetDTO(new Guid());
result.ShouldNotBeNull(); // don't pay attention I'll change stuff which has to be asserted
}
private SomeRepo DefaultSome(Some some = null)
{
some = some ?? A.Fake<ISome>();
/// HERE I TRIED TO MOCK STUFF IN DIFFERENT WAYS AND I HAVE AN ERROR
var policyWrap = A.Dummy<AsyncPolicyWrap>();
//var test = Policy.WrapAsync(A.Fake<AsyncRetryPolicy>(), A.Fake<AsyncCircuitBreakerPolicy>());
//var test = Policy.WrapAsync(A.Fake<IAsyncPolicy>(), A.Fake<IAsyncPolicy>());
A.CallTo(() =>
policyWrap.ExecuteAsync(A<Func<Task<HttpResponseMessage>>>._))
.Returns(new HttpResponseMessage(HttpStatusCode.OK));
var policy = A.Fake<RetryPolicies>();
A.CallTo(() =>
policy.PropName)
.Returns(policyWrap);
return new SomeRepo(some, ..., policy);
}
这是我收到的错误
我得到类似的注释//var test = ... variats
最佳答案
具体与抽象
每当你需要模拟某些东西时,就依赖抽象而不是具体的实现。
AsyncPolicyWrap
是一个具体类,而不是 abstract
像 AsyncPolicy
此外,异常表明此类没有公共(public)无参数构造函数。
它有一个 internal
有 2 个参数的 ctor:
internal AsyncPolicyWrap(AsyncPolicy outer, IAsyncPolicy inner)
: base(outer.ExceptionPredicates)
{
_outer = outer;
_inner = inner;
}
所以,你应该更喜欢AsyncPolicy
abstract
类或 IAsyncPolicy
界面。
有或没有结果
请注意,在 Polly 中,每个策略都有两个版本:
- 不返回任何结果
- 确实返回一些结果的一个
基于SomeRepo
您的策略应返回 HttpResponseMessage
的代码.
所以,你应该使用IAsyncPolicy<HttpResponseMessage>
或AsyncPolicy<HttpResponseMessage>
表明您的保单将返回 HttpResponseMessage
.
模拟
每当你 mock IAsyncPolicy<HttpResponseMessage>
时那么您不必重新创建组合策略(就像您在评论中所做的那样)。您所要做的就是定义 ExecuteAsync
应该如何表现得好。
幸福之路:
var mockedPolicy = new Mock<IAsyncPolicy<HttpResponseMessage>>();
mockedPolicy
.Setup(policy => policy.ExecuteAsync(It.IsAny<Func<Task<HttpResponseMessage>>>()))
.ReturnsAsync(new HttpResponseMessage(HttpStatusCode.OK));
不愉快的道路:
var mockedPolicy = new Mock<IAsyncPolicy<HttpResponseMessage>>();
mockedPolicy
.Setup(policy => policy.ExecuteAsync(It.IsAny<Func<Task<HttpResponseMessage>>>()))
.ThrowsAsync(new HttpRequestException("Something bad happened"));
我使用最小起订量来模拟该策略,但相同的概念也可以应用于 FakeItEasy。
关于c# - 如何使用 FakeItEasy 在 .Net Core 中模拟 AsyncPolicyWrap 或 AsyncPolicy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71683824/