简体   繁体   中英

Mocked object returning null object instead of List

Using Moq, I have a mocked object that is supposed to return a List<> from a function call. The object that is returned is null and I am not sure why.

Here I create the mocked object and setup the function to return a List

var mockParser = new Mock<ISalesParser>() { CallBase = false };
        mockParser.Setup(m => m.Parse(It.IsAny<string>())).Returns(new List<ImportedData>{ new ImportedData{ ReportingPeriod = DateTime.Now } });

It the function under test, I call Parse() and capture the object returned. When I try to get the Count of the list, it throws a System.ArgumentNullExcpetion : Value cannot be null exception.

I'm pretty new to mocking and Moq, is there something i'm missing?

Test Method:

[Test]
    public void Test_ImportNormalExecution()
    {
        var importedData = new Mock<List<ImportedData>>(MockBehavior.Strict) { CallBase = false };
        importedData.SetupAllProperties();
        importedData.As<IEnumerable<ImportedData>>().Setup(m => m.GetEnumerator()).Returns(importedList.GetEnumerator());

        var mockParser = new Mock<ISalesParser>() { CallBase = false };
        mockParser.Setup(m => m.Parse(It.IsAny<string>())).Returns(new List<ImportedData>{ new ImportedData{ ReportingPeriod = DateTime.Now } });
        mockParser.Setup(m => m.Parse(It.IsAny<string>())).Callback(() => parseFuncCall++);

        var mockContext = new Mock<ApplicationDbContext>() { CallBase = true };
        mockContext.As<IUnitOfWork>().CallBase = false;
        mockContext.Setup(m => m.ImportedData.Add(It.IsAny<ImportedData>())).Callback(() => addImportDataCall++);

        unitOfWork = new UnitOfWork(mockContext.Object);
        dataRepository = new ImportedDataRepository(mockContext.Object);
        parser = mockParser.Object;

        service = new SalesService(parser, dataRepository, unitOfWork);
        string status = "Parsed input file.  Processed imported data into sales history.";
        SalesImportResults results = ((ISalesService)service).Import(AmazonHtmlSalesParserResources.AmazonHtmlDataValid);

        Assert.AreEqual(1, results.Count);
        Assert.That(parseFuncCall == 1);
        Assert.That(addImportDataCall == 1);
        Assert.That(String.Compare(status, results.Status) == 0);

    }

Method under test

public SalesImportResults ISalesService.Import(string data)
    {
        var salesImportResults = new SalesImportResults();

        try
        {
            IEnumerable<ImportedData> sales = _salesParser.Parse(data);

            salesImportResults.Count = sales.Count();
            salesImportResults.Date = sales.FirstOrDefault().ReportingPeriod;
            salesImportResults.Status = "Parsed input file.";

            foreach (ImportedData salesItem in sales)
            {
                _importedDatarepository.Add(salesItem);
            }
            _unitOfWork.SaveChanges();

            salesImportResults.Status += " Inserted data into import table.";

            _importedDatarepository.ProcessImportedData();

            salesImportResults.Status += " Processed imported data into sales history.";

            return salesImportResults;
        }
        catch (Exception ex)
        {
            throw new ApplicationException(salesImportResults.Status + " - but then something went wrong: " + ex.Message, ex);
        }

    }

The exception gets thrown on the line salesImportResults.Count = sales.Count();

public interface ISalesParser
{
    IEnumerable<ImportedData> Parse(string data);
}

When you call

mockParser.Setup(m => m.Parse(It.IsAny<string>())).Callback(() => parseFuncCall++);

previously configured return value is reset, so it's null again. If you need to setup a return value and a callback, you can chain Returns and Callback methods together:

var mockParser = new Mock<ISalesParser>() { CallBase = false };
mockParser.Setup(m => m.Parse(It.IsAny<string>()))
    .Returns(new List<ImportedData>{ new ImportedData{ ReportingPeriod = DateTime.Now } })
    .Callback(() => parseFuncCall++);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM