0

I have the following class I want to test:

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;
    }
}

Specifically, I want to test the GetData method. My unit test looks like this:

[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);
    }
}

The error I am getting happens on the last line:

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

And the exact error message is this:

{"\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)"}

Any idea why this is happening? It looks to me like the method in question is being called, but Moq doesn't like the parameters for some reason, even though they are the exact same ones in all three invocations, as far as I can tell.

lukegf
  • 2,147
  • 3
  • 26
  • 39
  • 1
    I'm fairly sure it's because `PagedTable` is a reference type not a value type. Therefore the parameters in `Setup` don't match what was called even though they look like they should be the same. You could use `It.IsAny()` instead of tempResult. You could check that the PagedTable used was the one expected using the technique in http://stackoverflow.com/a/4963632/2131092 – Andy Nichols Jan 26 '16 at 16:27
  • Thanks, that worked! I knew it was some syntax issue like that. – lukegf Jan 26 '16 at 16:45
  • @AndyNichols I am trying to mark your answer as the accepted one, but there is no checkmark by it, that I can see anyway. Is there some time after which the checkmark will appear? – lukegf Jan 26 '16 at 17:17
  • It's because it's a comment not an answer. I'll add as an answer now. – Andy Nichols Jan 26 '16 at 17:20

1 Answers1

4

PagedTable is a reference type not a value type. Therefore the parameters in Setup don't match what was called even though they look like they should be the same. You could use It.IsAny<PagedTable>() instead of tempResult.

See this answer for an example of how to check that the PagedTable parameter was the correct one.

Community
  • 1
  • 1
Andy Nichols
  • 2,952
  • 2
  • 20
  • 36