Moq를 사용하여 메소드 호출 확인


142

저는 C #에서 단위 테스트를 처음 접했고 Moq를 사용하는 법을 배우고 있습니다. 아래는 내가 테스트하려고하는 수업입니다.

class MyClass
{
    SomeClass someClass;
    public MyClass(SomeClass someClass)
    {
        this.someClass = someClass;     
    }

    public void MyMethod(string method)
    {
        method = "test"
        someClass.DoSomething(method);
    }   
}

class Someclass
{
    public DoSomething(string method)
    {
        // do something...
    }
}

아래는 내 TestClass입니다.

class MyClassTest
{
    [TestMethod()]
    public void MyMethodTest()
    {
        string action="test";
        Mock<SomeClass> mockSomeClass = new Mock<SomeClass>();
        mockSomeClass.SetUp(a => a.DoSomething(action));
        MyClass myClass = new MyClass(mockSomeClass.Object);
        myClass.MyMethod(action);
        mockSomeClass.Verify(v => v.DoSomething(It.IsAny<string>()));
    }
}

다음과 같은 예외가 있습니다.

Expected invocation on the mock at least once, but was never performed
No setups configured.
No invocations performed..

"MyMethod"메소드가 호출되고 있는지 확인하고 싶습니다. 뭔가 빠졌습니까?


1
SomeClass대한 정의 가 없으면 컴파일 MyMethod(string)되지 않습니다.
Platinum Azure

죄송합니다 .. 내 질문을 편집했습니다 ..
user591410

1
올바른 길을 가고 있지만 게시 된 코드에 버그가 있습니다. 컴파일되지 않습니다-Someclass에서 케이싱, DoSomething에서 void 반환. 그런 다음 공개 액세스가 필요하며 DoSomething을 가상으로 만드십시오. 간단히 말해 프로덕션 코드에도 버그가있을 수 있습니다.
TrueWill

답변 주셔서 감사합니다. 모의 메서드를 설정하는 동안 인수를 잘못 설정했습니다 ..
user591410

"설정이 구성되지 않았습니다." 오해의 소지가 있습니다. 호출 될 메소드의 동작을 설정할 필요가 없습니다. 또한 테스트중인 메소드를 호출 한 후 "확인"메소드를 실행해야합니다 (따라서 괜찮습니다).
Sielu

답변:


209

잘못된 방법을 확인 중입니다. Moq를 사용하려면 종속성 클래스에서 메소드를 설정 한 다음 선택적으로 확인해야합니다.

다음과 같은 작업을 수행해야합니다.

class MyClassTest
{
    [TestMethod]
    public void MyMethodTest()
    {
        string action = "test";
        Mock<SomeClass> mockSomeClass = new Mock<SomeClass>();

        mockSomeClass.Setup(mock => mock.DoSomething());

        MyClass myClass = new MyClass(mockSomeClass.Object);
        myClass.MyMethod(action);

        // Explicitly verify each expectation...
        mockSomeClass.Verify(mock => mock.DoSomething(), Times.Once());

        // ...or verify everything.
        // mockSomeClass.VerifyAll();
    }
}

다시 말해, 당신은 MyClass#MyMethodcall을 확인하고 있으며 , SomeClass#DoSomething그 과정에서 클래스가 확실히 한 번 호출 합니다. Times인수는 필요하지 않습니다 . 나는 단지 그 가치를 보여주고 있었다.


죄송합니다. 올바른 방법으로 질문을 편집했습니다. 언급했듯이 먼저 설정을 시도한 다음 확인을 수행했습니다. 여전히 같은 예외가 있습니다.
user591410

22
기대치를 설정하고 동일한 기대치를 명시 적으로 검증하는 것이 중복되지 않습니까? mockSomeClass.VerifyAll();동일한 결과를 얻지 못하고 더 건조합니까?
Tim Long

14
그렇습니다. 그러나 일부 사람들은 명시적인 태도를 선호합니다.
Platinum Azure

3
적어도 VerifyAll ()을 언급 해 주셔서 감사합니다. 일단 당신이 그것에 대해 생각하면 분명합니다. 나는 명백한 접근 방식을 사용했을 수도 있지만 모든 것을 사용할 때 훨씬 깨끗합니다. 둘 다 감사합니다.
JGood

1
Mock비교할 때의 한 가지 단점은 NSubstitute매개 변수도 확인하려고 시도하고 확인이 실패하면 수행 된 호출을 보여 주지만 확인 표현식에 변수를 사용한 경우 정확히 예상 한 것은 표시하지 않는다는 것입니다. 값이 아닌 이름이므로 변수에 정확히 어떤 값이 있는지 확인하기 위해 디버그해야합니다. NSubstitute는 둘 다의 값과 다른 값을 보여줍니다.
그렌 가스
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.