메소드가 호출되는지 확인하기 위해 Moq 사용


159

더 높은 수준의 메서드를 호출하면 메서드 호출이 발생하는지 테스트 할 수 있습니다.

public abstract class SomeClass()
{    
    public void SomeMehod()
    {
        SomeOtherMethod();
    }

    internal abstract void SomeOtherMethod();
}

전화하면 전화가 SomeMethod()올 것으로 예상합니다 SomeOtherMethod().

이런 종류의 테스트가 조롱 프레임 워크에서 사용할 수 있다고 생각합니까?

답변:


186

확인을 사용하여 조롱 한 메소드의 메소드가 호출되었는지 확인할 수 있습니다. 예 :

static void Main(string[] args)
{
        Mock<ITest> mock = new Mock<ITest>();

        ClassBeingTested testedClass = new ClassBeingTested();
        testedClass.WorkMethod(mock.Object);

        mock.Verify(m => m.MethodToCheckIfCalled());
}

class ClassBeingTested
{
    public void WorkMethod(ITest test)
    {
        //test.MethodToCheckIfCalled();
    }
}

public interface ITest
{
    void MethodToCheckIfCalled();
}

줄이 주석 처리 된 경우 확인을 호출하면 MockException이 발생합니다. 주석 처리가 없으면 통과합니다.


7
이것이 정답입니다. 그러나 무언가를 이해해야합니다. 추상 또는 가상이 아닌 메소드 / 프로퍼티를 모의 할 수 있습니다 (분명히 모든 인터페이스 메소드 및 특성을 모의 할 수 있음).

25
-1 :이 코드에서는 .Expect (...). Verifiable ()이 중복됩니다. AAA를 사용하면 확인하는 것이 옳습니다. .Verifiable은 .Verify () i와 함께 사용하기위한 것입니다. 인수 없음 버전 참조 stackoverflow.com/questions/980554/...
루벤 Bartelink

@
I--

6

모의 테스트는 테스트 가능한 특정 디자인 패턴을 사용한다고 가정합니다. 그 중 하나는 사출입니다. 귀하의 경우 테스트 SomeClass.SomeMethod 하고 SomeOtherMethod인터페이스 해야하는 다른 엔티티에서 구현해야합니다.

귀하의 Someclass생성자는 같을 것이다 New(ISomeOtherClass). 그런 다음 모의하고 ISomeOtherClass기대를 설정하고 기대를 SomeOtherMethod확인합니다.


0

@Paul 의 답변 이 권장되는 방법 이라는 데 동의하지만 moq자체적으로 제공하는 다른 방법을 추가하고 싶습니다 .

보낸 사람 SomeClass입니다 abstract그것은 참으로 mockable,하지만 public void SomeMehod()하지 않습니다. 요점은 그 방법을 조롱하고 어떻게 든 호출 한 다음 CallBase호출을 전파 하는 방법을 찾는 것 SomeOtherMethod()입니다. 그것은 해킹처럼 들릴 수 있지만 본질적으로 간단합니다. 제안 된 리팩토링이 불가능한 경우에 사용될 수 있습니다.

// This class is used only for test and purpose is make SomeMethod mockable
public abstract class DummyClass : SomeClass
{
    public virtual void DummyMethod() => base.SomeMethod();
}

그런 다음 플래그 DummyMethod()를 설정하여 호출을 전파하도록 설정할 수 CallBase있습니다.

//Arrange
var mock = new Mock<DummyClass>();
mock.Setup(m => m.DummyMethod()).CallBase();

//Act
mock.Object.SomeMethod();

//Assert
mock.Verify(m => m.SomeOtherMethod(), Times.Once);

더 복잡하고 보일러 DummyClass 필요 있기 때문에을 downvoted
reggaeguitar

때로는 리팩토링 할 수없고 구현을 테스트해야하므로 upvoted
wickdninja
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.