首页 > 解决方案 > 起订量,测试方法返回错误 - System.ArgumentNullException:值不能为空。(参数“来源”)

问题描述

我有以下服务:

DocumentTypeService班级_

public partial class DocumentTypeService : IDocumentTypeService
{
    private readonly IRepository<DocumentType> _documentTypeRepository;
    private readonly IMediator _mediator;

    public DocumentTypeService(IRepository<DocumentType> documentTypeRepository, IMediator mediator)
    {
        _documentTypeRepository = documentTypeRepository;
        _mediator = mediator;
    }

    public virtual async Task<IList<DocumentType>> GetAll()
    {
        var query = from t in _documentTypeRepository.Table
            orderby t.DisplayOrder
            select t;
        return await query.ToListAsync();
    }
}

再次测试GetAll()方法

[TestClass()]
public class DocumentTypeServiceTests
{
    private Mock<IRepository<DocumentType>> _documentTypeRepositoryMock;
    private DocumentTypeService _documentTypeService;
    private Mock<IMediator> _mediatorMock;

    [TestInitialize()]
    public void Init()
    {
        _mediatorMock = new Mock<IMediator>();
        _documentTypeRepositoryMock = new Mock<IRepository<DocumentType>>();
        _documentTypeService = new DocumentTypeService(_documentTypeRepositoryMock.Object, _mediatorMock.Object);
    }


    [TestMethod()]
    public async Task GetAllDocumentTypes()
    {
        await _documentTypeService.GetAll();
        _documentTypeRepositoryMock.Verify(c => c.Table, Times.Once);
    }
}

GetAllDocumentTypes()方法返回的错误

测试方法 Grand.Services.Tests.Documents.DocumentTypeServiceTests.GetAllDocumentTypes 抛出异常:
System.ArgumentNullException:值不能为空。(参数'source')
堆栈跟踪:
Queryable.OrderBy[TSource,TKey](IQueryable'1 source, Expression'1 keySelector)
MongoQueryable.OrderBy[TSource,TKey](IMongoQueryable'1 source, Expression'1 keySelector)

更新:

/// <summary>
/// MongoDB repository
/// </summary>
public partial class Repository<T> : IRepository<T> where T : BaseEntity
{
    /// <summary>
    /// Gets a table
    /// </summary>
    public virtual IMongoQueryable<T> Table
    {
        get { return _collection.AsQueryable(); }
    }
}

标签: c#.net-coremoq

解决方案


您应该模拟以下方法调用:

_documentTypeRepository.Table

具体来说,你需要这样的东西:

_documentTypeRepositoryMock = new Mock<IRepository<DocumentType>>();
var mongoQueryableMock = new Mock<IMongoQueryable<DocumentType>>();
_documentTypeRepositoryMock.Setup(x=>x.Table).Returns(mongoQueryableMock);

这样做,当_documentTypeRepository.Table被调用时将返回一个空列表,DocumentType并且不需要调用 OrderBy。默认行为是,因为您不模拟此调用,所以_documentTypeRepository.Table返回 null。因此稍后会出现空指针异常。

为了理解后一个参数,您应该了解查询语法是如何编译的。查询语法只是语法糖。编译代码时,首先将其替换为等效的(“LINQ”)方法调用,并生成相应的 IL 代码。所以你的查询:

from t in _documentTypeRepository.Table
orderby t.DisplayOrder
select t;

将首先在如下查询中进行转换:

_documentTypeRepository.Table
                       .OrderBy(x=>x)
                       .Select(x=>x)

稍后将根据后一个查询生成相应的 IL 代码。

因此,如果_documentTypeRepository.Table返回 null,则调用OrderBy将引发空指针异常。


推荐阅读