Moq : 재정의 할 수없는 구성원에 대한 잘못된 설정 : x => x.GetByTitle ( "asdf")


111

이 문제를 어떻게 해결할 수 있는지 확실하지 않고 "GetByTitle"메서드에서 단위 테스트를 시도합니다.

내 정의는 다음과 같습니다.

public class ArticleDAO :  GenericNHibernateDAO(IArticle, int>, IArticleDAO
{
    public IArticle GetByTitle(string title)
    {
        IQuery query = Session.CreateQuery("...")
        return query.UniqueResult<IArticle>();
    }
}

public interface IArticleDAO
{
    IArticle GetByTitle(string title);
}

단위 테스트 :

[Test]
public void can_load_by_title()
{
    _mockDaoFactory.Setup(x => x.GetArticleDao())
                                .Returns(_mockArticleDao.Object);
    _mockArticleDao.Setup(x => x.GetByTitle("some title"))
                                .Returns(article1.Object);

    _articleManager.LoadArticle("some title");

    Assert.IsNotNull(_articleManager.Article);
}

테스트를 실행하면 오류가 발생합니다.

System.ArgumentException: Invalid setup on a non-overridable member:
x => x.GetByTitle("some title")

최신 정보

[Setup]모습 :

[Setup]
public void SetUp()
{
     _mockDaoFactory = new Mock<IDaoFactory>();
     _mockArticleDao = new Mock<ArticleDao>();

     _articleManager = new ArticleManager(_mockDaoFactory.Object);    
}

2
인스턴스화 _mockDaoFactory하고 _mockArticleDao어딘가에 있습니까? 수업이나 인터페이스를 조롱합니까
Tomas Aschan 2009

네, 인터페이스를 사용하여 [설정]에서 daofactory와 mockarticleDao를 조롱했습니다. DAO는 클래스를 사용하여 수행되었습니다.
mrblah 2009

@tomas 설정 코드로 질문을 업데이트했습니다.
mrblah 2009

2
내 대답에서 볼 수 있듯이 인터페이스를 모의 (내가 권장하는 것)하거나 GetByTitle방법을 표시해야 합니다 virtual.
Tomas Aschan 2009

또한 테스트의 첫 번째 줄이 설정 루틴으로 이동할 수있는 것처럼 보입니다 ...?
Tomas Aschan 2009

답변:


154

모의 객체의 동작을 제어하려면 (최소한 Moq에서) 인터페이스를 모의 처리하거나 제어하려는 동작이 가상으로 표시되어 있는지 확인해야합니다. 귀하의 의견에서 나는 인스턴스화 _mockArticleDao가 다음과 같이 수행 되도록 이해합니다 .

_mockArticleDao = new Mock<ArticleDAO>();

그대로 유지하려면 GetArticle메소드 를 표시해야합니다 virtual.

public class ArticleDAO :  GenericNHibernateDAO(IArticle, int>, IArticleDAO
{
    public virtual IArticle GetByTitle(string title)
    {
        // ...
    }
}

그렇지 않으면 (그리고 이것이 내가 권장하는 것입니다) 대신 인터페이스를 조롱하십시오.

_mockArticleDao = new Mock<IArticleDAO>();

하지만 ArticleDAO는 Generic ....에서 상속 받았기 때문에 GenericNhibern에서 인터페이스를 모의 처리하면됩니다. 사용할 수 없게됩니까?
mrblah 2009

공장에서 GetArticleDAO를 호출하면 IArticleDAO가 아닌 ArticleDAO가 반환되기 때문에 b / c articleDAO는 nhibernate 항목이있는 추상 클래스에도 바인딩됩니다.
mrblah 2009

2
인터페이스를 조롱 할 수 없다면 잘못된 것을 테스트하고있을 수 있습니다.하지만 여전히 가상 메서드를 표시하면 문제가 해결됩니다.
Tomas Aschan 2009

+1 Tomas, 매개 변수를 ctor에 주입해야합니다. 따라서 제 경우에는 인터페이스의 ctor에 매개 변수를 주입 할 수 없기 때문에 실제 클래스를 모의하고 메서드를 가상으로 설정해야했습니다. 이것이 올바른 접근 방식입니까?
Houman

4
@Kave : 생성자에 무언가를 주입해야한다면 확실히 잘못된 것을 테스트하고있는 것입니다. 생성자에게 제공 한 것을 모의하고, 동작을 설정하고, 클래스가 올바른 방식으로 동작하는지 테스트 합니다. 필요한 경우 모든 메소드 서명에 액세스하기 위해 "주입 된"유형을 구현하는 새 인터페이스를 작성하십시오.
Tomas Aschan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.