Moq를 사용하여 단위 테스트를위한 비동기 메소드 조롱
웹 API
호출 을 수행하는 서비스의 메소드를 테스트하고 있습니다. HttpClient
웹 서비스 (솔루션의 다른 프로젝트에 위치)를 로컬로 실행하는 경우 표준을 사용하면 단위 테스트에 적합합니다.
그러나 변경 사항을 확인하면 빌드 서버가 웹 서비스에 액세스 할 수 없으므로 테스트가 실패합니다.
IHttpClient
인터페이스 를 만들고 응용 프로그램에서 사용하는 버전을 구현하여 단위 테스트를 위해이 문제를 해결할 방법을 고안했습니다 . 단위 테스트의 경우 모의 버전을 모의 비동기 게시 방법으로 완성합니다. 여기에 문제가 생겼습니다. HttpStatusResult
이 특정 테스트에 대해 OK를 반환하고 싶습니다 . 다른 유사한 테스트의 경우 나쁜 결과를 반환합니다.
테스트는 실행되지만 완료되지는 않습니다. 기다리고 있습니다. 나는 비동기 프로그래밍, 델리게이트 및 Moq 자체에 익숙하지 않고 새로운 것을 배우면서 잠시 동안 SO와 Google을 검색했지만 여전히이 문제를 극복 할 수없는 것 같습니다.
테스트하려는 방법은 다음과 같습니다.
public async Task<bool> QueueNotificationAsync(IHttpClient client, Email email)
{
// do stuff
try
{
// The test hangs here, never returning
HttpResponseMessage response = await client.PostAsync(uri, content);
// more logic here
}
// more stuff
}
내 단위 테스트 방법은 다음과 같습니다.
[TestMethod]
public async Task QueueNotificationAsync_Completes_With_ValidEmail()
{
Email email = new Email()
{
FromAddress = "bob@example.com",
ToAddress = "bill@example.com",
CCAddress = "brian@example.com",
BCCAddress = "ben@example.com",
Subject = "Hello",
Body = "Hello World."
};
var mockClient = new Mock<IHttpClient>();
mockClient.Setup(c => c.PostAsync(
It.IsAny<Uri>(),
It.IsAny<HttpContent>()
)).Returns(() => new Task<HttpResponseMessage>(() => new HttpResponseMessage(System.Net.HttpStatusCode.OK)));
bool result = await _notificationRequestService.QueueNotificationAsync(mockClient.Object, email);
Assert.IsTrue(result, "Queue failed.");
}
내가 무엇을 잘못하고 있지?
도와 주셔서 감사합니다.
작업을 생성하고 있지만 시작하지 않으므로 완료되지 않습니다. 그러나 작업을 시작하는 것이 아니라 사용으로 변경하면 Task.FromResult<TResult>
이미 완료된 작업이 제공됩니다.
...
.Returns(Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.OK)));
이 방법으로 실제 비동기 성을 테스트하지는 않습니다. 그렇게하려면 좀 더 Task<T>
세밀한 방식으로 제어 할 수 있는 작업을 만들려면 약간 더 많은 작업을 수행해야 합니다. 다른 날.
You might also want to consider using a fake for IHttpClient
rather than mocking everything - it really depends on how often you need it.
Recommend @Stuart Grassie's answer above.
var moqCredentialMananger = new Mock<ICredentialManager>();
moqCredentialMananger
.Setup(x => x.GetCredentialsAsync(It.IsAny<string>()))
.ReturnsAsync(new Credentials() { .. .. .. });
Using Mock.Of<...>(...)
:
var client = Mock.Of<IHttpClient>(c =>
c.PostAsync(It.IsAny<Uri>(), It.IsAny<HttpContent>()) == Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK))
);
'IT' 카테고리의 다른 글
IntPtr은 정확히 무엇입니까? (0) | 2020.06.01 |
---|---|
명명 규칙 : "상태"대 "상태" (0) | 2020.06.01 |
활동적인 사용자의 UserDetails를 얻는 방법 (0) | 2020.06.01 |
파이썬 CSV 문자열을 배열로 (0) | 2020.06.01 |
vs (0) | 2020.06.01 |