[英].NET CORE Testing - Mock IHttpContextAccessor with FakeItEasy
[英]How to mock AsyncPolicyWrap or AsyncPolicy in .Net Core using FakeItEasy
我有這樣的代碼(我必須測試一個回購協議,你會看到下面的代碼)
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
}
}
然后我有另一個回購協議 class
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"));
...
}
}
上面的 2 段代碼不能更改,因為它們在生產中,我作為初級開發人員只需要盡可能地用測試覆蓋代碼
我試過寫這樣的測試
[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
是具體的 class 而不是像AsyncPolicy
這樣的abstract
同樣作為例外,這個 class 沒有公共無參數構造函數。
它有一個帶有 2 個參數的internal
構造函數:
internal AsyncPolicyWrap(AsyncPolicy outer, IAsyncPolicy inner)
: base(outer.ExceptionPredicates)
{
_outer = outer;
_inner = inner;
}
因此,您應該更喜歡AsyncPolicy
abstract
class 或IAsyncPolicy
接口。
請注意,在 Polly 中,每個策略都有兩個版本:
根據SomeRepo
的代碼,您的策略應該返回一個HttpResponseMessage
。
因此,您應該使用IAsyncPolicy<HttpResponseMessage>
或AsyncPolicy<HttpResponseMessage>
來指示您的策略將返回HttpResponseMessage
。
每當您模擬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。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.