【问题标题】:Error "Expected invocation on the mock once, but was 0 times" when unit testing with moq使用 moq 进行单元测试时出现错误“预期在模拟上调用一次,但为 0 次”
【发布时间】:2016-05-03 06:24:22
【问题描述】:

我想测试以下课程:

public interface ISqlServiceByModule
{
    DataSet GetPagedAggregateData(int clientId, int moduleId, int billTypeId, PagedTable result);
}


public class IncidentModuleService : IIncidentModuleService
{
    private readonly ISqlServiceByModule sqlServiceByModule;

    public IncidentModuleService(ISqlServiceByModule sqlServiceByModule)
    {
        if (sqlServiceByModule == null) throw new ArgumentNullException("sqlServiceByModule");

        // Inject the ISqlServiceByModule dependency into the constructor
        this.sqlServiceByModule = sqlServiceByModule;
    }

    public PagedTable GetData(int clientId, int moduleId, int billTypeId, Dictionary<string, string> queryStringParameters)
    {            
        PagedTable result = new PagedTable(queryStringParameters);

        DataSet dataSet = this.sqlServiceByModule.GetPagedAggregateData(clientId, moduleId, billTypeId, result);

        // Map the DatSet to a PagedTable
        if (dataSet == null || dataSet.Tables.Count == 0)
        {
            result.SetPagesFromTotalItems(0);
        }
        else
        {
            result.SetPagesFromTotalItems(Convert.ToInt16(dataSet.Tables[1].Rows[0][0]));
            result.Listings = dataSet.Tables[0];
        }

        return result;
    }
}

具体来说,我想测试 GetData 方法。我的单元测试如下所示:

[TestClass]
public class IncidentModuleServiceUnitTest
{
    private DataSet incidentsData;

    [TestInitialize]
    public void SetUp()
    {
        this.incidentsData = new DataSet();
    }

    [TestMethod]
    public void GetDataTestGetPagedAggregateDataIsCalled()
    {
        //-- Arrange
        int billTypeId = 1;
        int clientId = 1;
        int moduleId = 1;
        Dictionary<string, string> queryStringParameters = new Dictionary<string,string>();
        PagedTable tempResult = new PagedTable(queryStringParameters);

        DataSet dataSet = new DataSet();
        dataSet.Tables.Add(new DataTable());

        var mockSqlService = new Mock<ISqlServiceByModule>();
        mockSqlService.Setup(r => r.GetPagedAggregateData(clientId, moduleId, billTypeId, tempResult)).Returns(this.incidentsData);
        IncidentModuleService target = new IncidentModuleService(mockSqlService.Object);

        //-- Act
        var actual = target.GetData(clientId, moduleId, billTypeId, queryStringParameters);

        //-- Assert
        Assert.IsNull(actual.Listings);
        mockSqlService.Verify(r => r.GetPagedAggregateData(clientId, moduleId, billTypeId, tempResult), Times.Once);
    }
}

我遇到的错误发生在最后一行:

mockSqlService.Verify(r => r.GetPagedAggregateData(clientId, moduleId, billTypeId, tempResult), Times.Once);

确切的错误信息是这样的:

{"\r\n预期在模拟上调用一次,但为 0 次:r => r.GetPagedAggregateData(.clientId, .moduleId, .billTypeId, .tempResult

已配置的设置:\r\nr => r.GetPagedAggregateData(.clientId, .moduleId, .billTypeId, .tempResult), Times.Never

执行的调用:\r\nISqlServiceByModule.GetPagedAggregateData(1, 1, 1, PagedTable)"}

知道为什么会这样吗?在我看来,有问题的方法正在被调用,但 Moq 出于某种原因不喜欢这些参数,尽管据我所知,它们在所有三个调用中完全相同。

【问题讨论】:

  • 我很确定这是因为PagedTable 是引用类型而不是值类型。因此Setup 中的参数与调用的参数不匹配,即使它们看起来应该相同。您可以使用 It.IsAny&lt;PagedTable&gt;() 代替 tempResult。您可以使用stackoverflow.com/a/4963632/2131092 中的技术检查所使用的 PagedTable 是否是预期的
  • 谢谢,成功了!我知道这是一些类似的语法问题。
  • @AndyNichols 我正在尝试将您的答案标记为已接受的答案,但它没有复选标记,无论如何我都可以看到。是否有一段时间会出现复选标记?
  • 这是因为它是评论而不是答案。我现在将添加为答案。

标签: unit-testing moq mstest


【解决方案1】:

PagedTable 是引用类型而不是值类型。因此,Setup 中的参数与调用的参数不匹配,即使它们看起来应该相同。您可以使用 It.IsAny&lt;PagedTable&gt;() 代替 tempResult。

有关如何检查 PagedTable 参数是否正确的示例,请参阅 this answer

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-15
    • 1970-01-01
    相关资源
    最近更新 更多