[C#] Moq에게 작업을 반환하도록하려면 어떻게해야합니까?

선언하는 인터페이스가 있습니다

Task DoSomethingAsync();

테스트에 MoqFramework를 사용하고 있습니다.

[TestMethod()]
public async Task MyAsyncTest()
{
   Mock<ISomeInterface> mock = new Mock<ISomeInterface>();
   mock.Setup(arg => arg.DoSomethingAsync()).Callback(() => { <my code here> });
   ...
}

그런 다음 테스트에서 호출하는 코드를 실행합니다 await DoSomethingAsync(). 그리고 테스트는 그 라인에서 실패합니다. 내가 뭘 잘못하고 있죠?



답변

메소드에 콜백이 없으므로 사용할 이유가 없습니다 .CallBack(). .Returns()and Task.FromResult를 사용하여 원하는 값으로 Task를 간단히 반환 할 수 있습니다 . 예 :

MyType someValue=...;
mock.Setup(arg=>arg.DoSomethingAsync())        
    .Returns(Task.FromResult(someValue));

2014-06-22 업데이트

Moq 4.2에는이를 지원하는 두 가지 새로운 확장 방법이 있습니다.

mock.Setup(arg=>arg.DoSomethingAsync())
    .ReturnsAsync(someValue);

mock.Setup(arg=>arg.DoSomethingAsync())        
    .ThrowsAsync(new InvalidOperationException());

2016 년 5 월 5 일 업데이트

세스 꽃이에 언급 된 바와 같이 다른 대답 , ReturnsAsync를 돌려주는 메소드에만 사용할 수 있습니다 Task<T>. 작업 만 반환하는 메서드의 경우

.Returns(Task.FromResult(default(object)))

사용할 수 있습니다.

이 답변 에서 볼 수 있듯이 .NET 4.6에서는 다음과 같이 단순화되었습니다 .Returns(Task.CompletedTask);.

mock.Setup(arg=>arg.DoSomethingAsync())        
    .Returns(Task.CompletedTask);


답변

비슷한 문제

대략 다음과 같은 인터페이스가 있습니다.

Task DoSomething(int arg);

조짐

테스트중인 서비스에서 awaited에 전화를 걸 때 유닛 테스트에 실패했습니다 DoSomething.

고치다

허용 대답과는 달리, 당신은 전화를 할 수없는 .ReturnsAsync()당신의 Setup()방법은 제네릭이 아닌를 반환하기 때문에이 시나리오에서이 방법 Task보다는 Task<T>.

그러나 .Returns(Task.FromResult(default(object)))설정에서 계속 사용할 수있어 테스트를 통과 할 수 있습니다.


답변

.Returns(Task.FromResult(0));콜백 후에 만 추가 하면됩니다.

예:

mock.Setup(arg => arg.DoSomethingAsync())
    .Callback(() => { <my code here> })
    .Returns(Task.FromResult(0));


답변

이제 Talentsoft.Moq.SetupAsync 패키지 https://github.com/TalentSoft/Moq.SetupAsync 를 사용할 수도 있습니다.

https://github.com/moq/moq4/issues/384 여기에서 발견 된 답변과 Moq에 제안되었지만 여전히 구현되지 않은 아이디어를 기반으로 비동기 메소드 설정을 크게 단순화합니다.

SetupAsync 확장으로 수행 된 이전 응답에서 몇 가지 예를 발견했습니다.

mock.SetupAsync(arg=>arg.DoSomethingAsync());
mock.SetupAsync(arg=>arg.DoSomethingAsync()).Callback(() => { <my code here> });
mock.SetupAsync(arg=>arg.DoSomethingAsync()).Throws(new InvalidOperationException());


답변