【问题标题】:Problem with matching setup in MoqMoq 中的匹配设置问题
【发布时间】:2010-12-13 19:29:08
【问题描述】:

过去一周左右我一直在使用 Moq,直到今天还没有遇到任何问题。我无法让 VerifyAll() 正确匹配我的模拟设置。

我目前正在为我的应用程序 API 编写单元测试。以下是应用程序的结构:

API <==> Service <==> DAO <==> Database

考虑到这一点,我正在模拟服务对象,然后使用模拟服务构造一个 API 对象。到目前为止,我已经编写了许多单元测试没有问题。

我有两个这样的实例变量:

private Api _api;
private Mock<IHibernateService> mockService;

我在设置方法中初始化这些:

[SetUp]
public void DoSetupTasks()
{
    mockService = new Mock<IHibernateService>();
    _api = new Api(mockService.Object);
}

这是失败的单元测试:

    [Test]
    public void TestSearchOnAllProperties()
    {
        mockService
            .Setup(service => service.LoadAll(It.IsAny<Type>()))
            .Returns(new DomainBase[0]);

        var dmbs = _api.SearchOnAllProperties("search term", typeof(DomainBase));

        mockService.VerifyAll();
    }

API 的SearchOnAllProperties() 方法随后将调用服务的LoadAll() 方法(当然还有一些额外的逻辑),所以我想验证它是否被正确调用。澄清一下,这是LoadAll()SearchOnAllProperties() 中的调用方式:

public IEnumerable<DomainBase> SearchOnAllProperties(string searchTerm, Type type)
{
    foreach (DomainBase dmb in _hibernateService.LoadAll(type))
    {
        // additional logic
    }
}

但是,当我运行单元测试时,我收到一个MockVerificationException,指出给定的设置不匹配。我不知道为什么它应该调用服务的LoadAll() 方法。

【问题讨论】:

    标签: c# .net unit-testing nunit moq


    【解决方案1】:

    一个可能的原因是在调用此特定测试方法之前的某个时间点,mockService 被分配给Mock&lt;IHibernateService&gt; 的新实例。如果是这种情况,那么这个测试方法会在错误的实例上调用Setup,然后会产生这个异常。

    一种快速的测试方法是使用本地的mockServiceapi 变量,看看测试是否仍然失败:

    [Test]
    public void TestSearchOnAllProperties()
    {
        var localMockService = new Mock<IHibernateService>();
        var localApi = new Api(localMockService.Object);
    
        localMockService
            .Setup(service => service.LoadAll(It.IsAny<Type>()))
            .Returns(new DomainBase[0]);
    
        var dmbs = localApi.SearchOnAllProperties("search term", typeof(DomainBase));
    
        localMockService.VerifyAll();
    }
    

    HTH

    【讨论】:

    • 我应该澄清一下,我已经尝试在测试用例中本地初始化 mockService 和 _api 并且问题仍然存在。
    • @Tyler,我复制了你的代码并通过了,所以 Moq 应该不是问题。您的 Api 类是否正在做任何可能将其内部 IHibernateService 变量分配给新实例的事情?
    • 当被匹配的方法调用是另一个表达式的一部分时,这似乎是一个问题,例如:foreach (Type t in _hibernateService.GetAllDomainTypes().Where(t =&gt; t.BaseType != null &amp;&amp; t.BaseType.Name == "DomainBase" &amp;&amp; !t.IsAbstract)。我已将模拟设置为严格,但也不例外。似乎根本没有调用任何方法。
    猜你喜欢
    • 2014-01-02
    • 1970-01-01
    • 1970-01-01
    • 2013-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-03
    相关资源
    最近更新 更多