使用最小起订量进行单元测试时出现错误 "Expected invocation on the mock once, but was 0 times"

Error "Expected invocation on the mock once, but was 0 times" when unit testing with moq

我有以下class我想测试:

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\nExpected invocation on the mock once, but was 0 times: r => r.GetPagedAggregateData(.clientId, .moduleId, .billTypeId, .tempResult

Configured setups:\r\nr => r.GetPagedAggregateData(.clientId, .moduleId, .billTypeId, .tempResult), Times.Never

Performed invocations:\r\nISqlServiceByModule.GetPagedAggregateData(1, 1, 1, PagedTable)"}

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

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

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