简体   繁体   English

具有规范模式和工作单元的单元测试未返回设置数据

[英]Unit Testing with Specification Pattern and Unit of Work is not returning data on setup

I have a generic Repository with the Unit of Work pattern setup to utilize the Specification Pattern which works great but now I am trying to Unit test it and it seems my setup isn't returning anything when specifying what to return.我有一个带有工作单元模式设置的通用存储库来利用规范模式,它工作得很好,但现在我正在尝试对其进行单元测试,似乎我的设置在指定要返回的内容时没有返回任何内容。

Repository Snippet存储库片段

 internal class Repository<T> : IRepository<T> where T : BaseEntity
{
    protected readonly ApplicationDbContext _context;

    public Repository(ApplicationDbContext context)
    {
        _context = context;
    }

    public IEnumerable<T> Find(ISpecification<T> specification = null)
    {
        return ApplySpecification(specification);
    }

    private IQueryable<T> ApplySpecification(ISpecification<T> spec)
    {
        return SpecificationEvaluator<T>.GetQuery(_context.Set<T>().AsQueryable(), spec);
    }
}

} }

Snippet of Specification规范片段

public class GetStocksForCurrentDaySpecification : BaseSpecification<Stock>
    {
        public GetStocksForCurrentDaySpecification() : base(x => x.DateInserted.Day == DateTime.Today.Day) { }
    }

Snippet of me calling it我叫它的片段

_unitOfWork.Repository<Stock>().Find(new GetStocksForCurrentDaySpecification());

This all works perfectly when running my code.运行我的代码时,这一切都完美无缺。

Here is my Unit Test where I do setup.这是我进行设置的单元测试。

[Fact]
        public void Job_Should_Execute()
        {
            var stockList = new List<Stock>();
            stockList.Add(new Stock
            {
                Id = Guid.NewGuid(),
                DateInserted = DateTime.Now,
                Exchange = "ASX",
                LongName = "Long Name",
                MarketOpenPrice = 1.26M,
                MarketPreviousClosePrice = 1.56M,
                MarketPrice = 1.3M,
                ShortName = "Short Name",
                Symbol = "LGN"
            });

            var stockRepositoryMock = new Mock<IRepository<Stock>>();
            stockRepositoryMock.Setup(m => m.Find(new GetStocksForCurrentDaySpecification())).Returns(stockList.ToArray());

            var unitOfWorkMock = new Mock<IUnitOfWork>();
            unitOfWorkMock.Setup(m => m.Repository<Stock>()).Returns(stockRepositoryMock.Object).Verifiable();

            var job = new YahooStockMarketJob(new HttpClient(), unitOfWorkMock.Object, new EventPublisher(_listeners), _configuration);
            job.Execute();

            unitOfWorkMock.Verify();
        }

When debugging, the following line returns an empty array instead of an array with one item it.调试时,以下行返回一个空数组,而不是一个包含一项的数组。

// Returns empty array
 var stockRepositoryMock = new Mock<IRepository<Stock>>();
            stockRepositoryMock.Setup(m => m.Find(new GetStocksForCurrentDaySpecification())).Returns(stockList.ToArray());

在此处输入图像描述

In your mock object you are setting up the Find method with a specific instance of GetStocksForCurrentDaySpecification .在您的模拟对象中,您正在使用GetStocksForCurrentDaySpecification的特定实例设置Find方法。 During your test you are passing a different instance of GetStocksForCurrentDaySpecification and since those are not the same it won't use that setup.在您的测试期间,您将传递不同的GetStocksForCurrentDaySpecification实例,并且由于这些实例不同,因此不会使用该设置。

If you want your setup to work with your test you either need to use the same instance or allow any instance of the object by using It.IsAny<T> .如果您希望您的设置与您的测试一起使用,您需要使用相同的实例或使用It.IsAny<T>允许对象的任何实例。

Eg例如

// Returns empty array
var stockRepositoryMock = new Mock<IRepository<Stock>>();
stockRepositoryMock
    .Setup(m => m.Find(It.IsAny<GetStocksForCurrentDaySpecification>()))
    .Returns(stockList.ToArray());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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