使用 InMemoryDatabase Return 计数 0 的 NUnit 测试

NUnit Test With InMemoryDatabase Return Count 0

我正在使用 InMemoryDatabase 实施一些 NUnit 测试。

当我有测试保存在数据库中时它工作,该测试已经通过,但如果我想在单独的测试方法中将 return 列表作为结果。该列表为空,return计数为 0,而不是 300。

测试方法 GetPaymentCalendar_WithFactoryIdRequest_ReturnCount 失败。

有人可以给我提示吗,我做错了什么?

public class PaymentCalendarRequestServiceTests
{
    private IPaymentCalendarService _paymentCalendarService;
    private ApplicationDbContext _context;
    private IUnitOfWork _unitOfWork;

    [SetUp]
    public void Init()
    {
        var options = new DbContextOptionsBuilder<ApplicationDbContext>()
            .UseInMemoryDatabase("TestDb")
            .Options;
        var currentUserServiceMock = new Mock<ICurrentUserService>(MockBehavior.Strict);
        currentUserServiceMock.Setup(_ => _.UserId).Returns(Guid.NewGuid().ToString);
        var dateTimeServiceMock = new Mock<IDateTimeService>(MockBehavior.Strict);
        dateTimeServiceMock.Setup(_ => _.Now).Returns(DateTime.Now);
        _context = new ApplicationDbContext(options, currentUserServiceMock.Object, dateTimeServiceMock.Object);
        _unitOfWork = new UnitOfWork(_context, dateTimeServiceMock.Object, currentUserServiceMock.Object);

        _paymentCalendarService = new PaymentCalendarService(_unitOfWork);
    }

    [Test]
    public void CreatePaymentCalendar_WithValidPaymentCalendarCreateRequest_ReturnSuccess()
    {
        var request = new List<PaymentCalendarCreateRequest>();
        for (int i = 0; i < 25 * 12; i++)
        {
            request.Add(
                new PaymentCalendarCreateRequest
                {
                    Month = DateTime.Now.AddMonths(i).Month,
                    Year = DateTime.Now.AddMonths(i).Year,
                    IsClosed = false,
                    FactoryId = "25aa09a6-006c-4571-ae45-68b697a54fec"
                }
            );
        }
        var result = _paymentCalendarService.CreatePaymentCalendar(request).Result;
        Assert.IsTrue(result.Succeeded);
    }

    [Test]
    public void GetPaymentCalendar_WithFactoryIdRequest_ReturnCount()
    {
        var factoryId = "25aa09a6-006c-4571-ae45-68b697a54fec";
        var response = _paymentCalendarService.GetPaymentCalendar(factoryId).Result;
        Assert.AreEqual(25*12,response.Count);
    }
}

来自 NUnit 文档:

SetUp

This attribute is used inside a TestFixture to provide a common set of functions that are performed just before each test method is called.

所以您[设置]中的所有内容都将在每个测试之前完成。

这意味着,您的数据库每次都将使用空方案进行初始化

正如已经给出的答案所确定的那样,您的设置是 运行 针对每个测试单独设置的。没有结转状态。但是我想在这个答案中解决的是不应该有结转,因为您仍在寻找一种方法来响应先前给出的结转回答。

当您想编写数据检索测试时设置数据应该是该测试的一部分。不应使用其他测试来设置数据,因为这会在测试和它们的执行顺序之间产生依赖性,您希望非常避免这种情况。每个测试都应该是独立的,你应该能够 运行 他们(并让他们有意义)单独。

即使是集成测试,测试也应该设置自己的数据。理想情况下,它也会自行清理,但如果在测试套件 运行 之后丢弃数据库(并且未清理数据的存在不会干扰其他测试),则可以跳过该操作。

[Test]
public void GetPaymentCalendar_WithFactoryIdRequest_ReturnCount()
{
    // Set the data you want to be available in the db here

    var factoryId = "25aa09a6-006c-4571-ae45-68b697a54fec";
    var response = _paymentCalendarService.GetPaymentCalendar(factoryId).Result;
    Assert.AreEqual(25*12,response.Count);
}

换句话说,类似于:

[Test]
public void GetPaymentCalendar_WithFactoryIdRequest_ReturnCount()
{
    var factoryId = "25aa09a6-006c-4571-ae45-68b697a54fec";

    _context.Payments.Add(new Payment() { ... });
    _context.Payments.Add(new Payment() { ... });
    _context.Payments.Add(new Payment() { ... });
    _context.SaveChanges();

    var response = _paymentCalendarService.GetPaymentCalendar(factoryId).Result;
    
    Assert.AreEqual(3,response.Count);
}

我不知道你的数据模型,所以这里的代码有一些明显的漏洞。主要目的是突出这里应该发生的事情,你必须自己填写细节。

随意添加 helper/private 方法来抽象出庞大的排列逻辑,这样您就可以让测试主体主要关注被测试的内容,而不是如何排列它。