Moq를 사용하여 살펴 보았지만 Callback
사용 방법을 이해하는 간단한 예제를 찾을 수 없었습니다.
사용 방법과시기를 명확하게 설명하는 작은 작업 스 니펫이 있습니까?
답변
이기기 어렵다 https://github.com/Moq/moq4/wiki/Quickstart
그것이 충분히 명확하지 않다면 나는 그것을 문서 버그라고 부를 것입니다.
편집 : 귀하의 설명에 대한 응답으로 …
Setup
수행하는 각 모의 방법에 대해 다음과 같은 것을 나타냅니다.
- 입력에 대한 제약
- 반환 값 (있는 경우)이 파생되는 방법에 대한 값
.Callback
메커니즘은 “나는 지금 그것을 설명 할 수는 없지만이 모양의 호출이 발생했을 때, 내가 다시 전화해서 내가 일을해야 일을 할 것이다”라고. 동일한 유창한 콜 체인의 일부로 .Returns
” 를 통해 반환 할 결과 (있는 경우)를 제어 할 수 있습니다 . QS 예제에서 반환되는 값이 매번 증가하도록 만드는 것이 예입니다.
일반적으로 이와 같은 메커니즘은 자주 필요하지 않으며 (xUnit 테스트 패턴에는 테스트에서 ilk 조건부 논리의 반 패턴에 대한 용어가 있습니다) 필요한 것을 설정하는 더 간단하거나 내장 된 방법이 있다면 선호도에 사용됩니다.
Justin Etheredge의 Moq 시리즈 4 부 중 3 부에서 이를 다룹니다. 여기에 콜백의 또 다른 예가 있습니다.
콜백의 간단한 예는 Moq 게시물 에서 콜백 사용 에서 찾을 수 있습니다 .
답변
다음은 삽입을 처리하는 데이터 서비스에 전송 된 엔터티를 테스트하기 위해 콜백을 사용하는 예입니다.
var mock = new Mock<IDataService>();
DataEntity insertedEntity = null;
mock.Setup(x => x.Insert(It.IsAny<DataEntity>())).Returns(1)
.Callback((DataEntity de) => insertedEntity = de);
대체 일반 메서드 구문 :
mock.Setup(x => x.Insert(It.IsAny<DataEntity>())).Returns(1)
.Callback<DataEntity>(de => insertedEntity = de);
그런 다음 다음과 같은 것을 테스트 할 수 있습니다.
Assert.AreEqual("test", insertedEntity.Description, "Wrong Description");
답변
Callback
Moq 에는 두 가지 유형이 있습니다 . 호출이 반환되기 전에 하나가 발생합니다. 다른 하나는 호출이 반환 된 후에 발생합니다.
var message = "";
mock.Setup(foo => foo.Execute(arg1: "ping", arg2: "pong"))
.Callback((x, y) =>
{
message = "Rally on!";
Console.WriteLine($"args before returns {x} {y}");
})
.Returns(message) // Rally on!
.Callback((x, y) =>
{
message = "Rally over!";
Console.WriteLine("arg after returns {x} {y}");
});
두 콜백 모두에서 다음을 수행 할 수 있습니다.
- 메서드 인수 검사
- 캡처 메서드 인수
- 상황 별 상태 변경
답변
Callback
모의 메소드 중 하나를 호출 할 때 원하는 사용자 정의 코드를 실행하는 수단 일뿐입니다. 다음은 간단한 예입니다.
public interface IFoo
{
int Bar(bool b);
}
var mock = new Mock<IFoo>();
mock.Setup(mc => mc.Bar(It.IsAny<bool>()))
.Callback<bool>(b => Console.WriteLine("Bar called with: " + b))
.Returns(42);
var ret = mock.Object.Bar(true);
Console.WriteLine("Result: " + ret);
// output:
// Bar called with: True
// Result: 42
최근에 흥미로운 사용 사례를 접했습니다. 모의에 대한 일부 호출을 예상하지만 동시에 발생한다고 가정합니다. 따라서 호출되는 순서를 알 수있는 방법이 없지만 예상 한 호출이 (순서에 관계없이) 발생했는지 알고 싶습니다. 다음과 같이 할 수 있습니다.
var cq = new ConcurrentQueue<bool>();
mock.Setup(f => f.Bar(It.IsAny<bool>())).Callback<bool>(cq.Enqueue);
Parallel.Invoke(() => mock.Object.Bar(true), () => mock.Object.Bar(false));
Console.WriteLine("Invocations: " + String.Join(", ", cq));
// output:
// Invocations: True, False
BTW는 오해의 소지가있는 “이전 Returns
“과 “이후 Returns
“구분으로 혼동하지 않습니다 . 사용자 지정 코드가 Returns
평가 된 후 또는 이전에 실행되는지 여부에 대한 기술적 인 차이 일뿐 입니다. 호출자의 눈에는 값이 반환되기 전에 둘 다 실행됩니다. 실제로 메서드가 void
-returning이면 호출조차 할 수 없지만 여전히 Returns
동일하게 작동합니다. 자세한 내용은 https://stackoverflow.com/a/28727099/67824를 참조 하십시오 .
답변
여기에 다른 좋은 답변 외에도 예외를 던지기 전에 논리를 수행하는 데 사용했습니다. 예를 들어, 나중에 확인하기 위해 메서드에 전달 된 모든 개체를 저장해야했고 해당 메서드 (일부 테스트 사례에서)는 예외를 throw해야했습니다. 호출 은 작업 .Throws(...)
을 Mock.Setup(...)
무시하고 Callback()
호출하지 않습니다. 그러나 콜백 내에서 예외를 throw하면 콜백이 제공해야하는 모든 좋은 작업을 수행 할 수 있으며 여전히 예외를 throw 할 수 있습니다.
답변
