다음 인터페이스가 제공됩니다.
public interface IFoo
{
bool Foo(string a, bool b = false);
}
Moq를 사용하여 모의 시도 :
var mock = new Mock<IFoo>();
mock.Setup(mock => mock.Foo(It.IsAny<string>())).Returns(false);
컴파일 시간에 다음 오류를 제공합니다.
표현식 트리는 선택적 인수를 사용하는 호출 또는 호출을 포함 할 수 없습니다.
위의 문제 가 Moq의 문제 목록에서 개선 된 것으로 제기되었으며 4.5 릴리스에 할당 된 것으로 보입니다 (그럴 때마다).
내 질문은 위의 내용이 곧 수정되지 않을 경우 어떻게해야합니까? 내가 모의 할 때마다 선택적 매개 변수의 기본값을 명시 적으로 설정하거나 (처음에 하나를 지정하는 점을 무너 뜨리는) 부울없이 오버로드를 생성하는 옵션 만 있습니까 (내가했던 것처럼 C # 4 이전)?
아니면이 문제를 극복하기 위해 더 현명한 방법을 찾은 사람이 있습니까?
답변
현재 유일한 선택 bool
은 설정에 매개 변수 를 명시 적으로 포함하는 것 입니다 Foo
.
나는 그것이 기본값을 지정하는 목적을 훼손한다고 생각하지 않습니다. 기본값은 코드 호출의 편의성이지만 테스트에서 명시 적이어야한다고 생각합니다. bool
매개 변수 지정을 생략 할 수 있습니다. 미래에, 누군가의 기본값 변경하면 어떻게됩니까 b
에를 true
? 이것은 실패한 테스트로 이어질 것입니다 (그리고 당연히 그렇습니다), 숨겨진 가정 때문에 수정하기가 더 어려울 것 b
입니다 false
. bool
매개 변수를 명시 적으로 지정하면 테스트의 가독성이 향상된다는 또 다른 이점이 있습니다. 그것들을 살펴 보는 누군가 Foo
는 두 개의 매개 변수를 받아들이는 하나의 함수가 있다는 것을 금방 알게 될 것입니다 . 그것은 적어도 내 2 센트입니다 🙂
조롱 할 때마다 지정하는 것과 관련하여 코드를 복제하지 마십시오. 함수에서 모의 객체를 생성 및 / 또는 초기화하여 단일 변경 지점 만 갖도록하십시오. 정말로 원한다면 Foo
의 매개 변수를이 초기화 함수 에 복제하여 Moq의 명백한 단점을 극복 할 수 있습니다 .
public void InitFooFuncOnFooMock(Mock<IFoo> fooMock, string a, bool b = false)
{
if(!b)
{
fooMock.Setup(mock => mock.Foo(a, b)).Returns(false);
}
else
{
...
}
}
답변
오늘이 문제가 발생하여 Moq는이 사용 사례를 지원하지 않습니다. 따라서이 경우 메서드를 재정의하는 것으로 충분할 것 같습니다.
public interface IFoo
{
bool Foo(string a);
bool Foo(string a, bool b);
}
이제 두 가지 방법을 모두 사용할 수 있으며이 예제는 작동합니다.
var mock = new Mock<IFoo>();
mock.Setup(mock => mock.Foo(It.IsAny<string>())).Returns(false);
답변
Moq 버전 4.10.1을 사용하여 다음을 수행 할 수있었습니다.
인터페이스 :
public interface IFoo
{
bool Foo(string a, bool b = false);
}
그리고 모의
var mock = new Mock<IFoo>();
mock.Setup(mock => mock.Foo(It.IsAny<string>(), It.IsAny<bool>())).Returns(false);
첫 번째 매개 변수가 okay 인 Foo에 대한 호출을 해결합니다.