使用 NSubstitute 4.0 模拟 EF dbContext 异步方法

问题描述 投票:0回答:1

尝试在 DbContext 上使用 NSubstitute 时出现错误。到目前为止,我使用 EntityFramework.Testing 包和以下代码在测试中设置我的 DbContext。这很简单,这是他们网站上的示例:

// Create some test data
var data = new List<Blog>
{
    new Blog{ Name = "BBB" },
    new Blog{ Name = "CCC" },
    new Blog{ Name = "AAA" }
};

// Create a DbSet substitute.
var set = Substitute.For<DbSet<Blog>, IQueryable<Blog>, IDbAsyncEnumerable<Blog>>()
                    .SetupData(data);

var context = Substitute.For<BloggingContext>();
context.Blogs.Returns(set);

这与版本

3.1.0
配合得很好,但如果我将 NSubstitute 升级到
4.0
,则会引发以下异常。

系统.MissingMethodException 未找到方法:“System.__Canon NSubstitute.Arg.Any()”。 NSubstitute.NSubstituteDbSetExtensions.SetupData[TEntity](DbSet'1 dbSet, ICollection'1 数据, Func'2 查找)

我想知道是否有一个好的解决方案来模拟具有异步支持的 EF 上下文,或者我应该坚持使用 3.1.0。

c# entity-framework unit-testing mocking nsubstitute
1个回答
0
投票
[TestFixture]
public class InvoicesControllerTests
{
    private InvoicesController _controller;
    private BdAgendaTChampionContext _context;

    [SetUp]
    public void SetupInvoice()
    {
        // Mock the context
        var options = new DbContextOptionsBuilder<BdAgendaTChampionContext>()
            .UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString())
            .Options;

        _context = new BdAgendaTChampionContext(options);

        //// Seed the in-memory database with substitute data
        _context.Invoices.AddRange(Substitute.For<Invoice>());
        _context.InvoiceDetails.AddRange(Substitute.For<InvoiceDetail>());
        _context.Customers.AddRange(Substitute.For<Customer>());

        _context.SaveChanges();

        // Initialize the controller
        _controller = new InvoicesController(_context);
    }

    [TestFixture]
    public class Update : InvoicesControllerTests
    {
        [Test]
        public void InvoiceStatusID_ShouldReturnOK()
        {
            //Arrange
            int vKey = 1;
            var vUpdatedStatus = 30;
            var vValue = new { InvoiceStatusId = vUpdatedStatus };
            var vData = JsonConvert.SerializeObject(vValue);

            //Act
            var vResult = _controller.Update(vKey, vData);

            //Asset

            var vInvoice = _context.Invoices.First(i => i.InvId == vKey);
            Assert.That(vUpdatedStatus, Is.EqualTo(vInvoice.StatusId));
            Assert.That(vResult, Is.TypeOf<OkResult>());
        }
    }

嗨,我在 IQueryable 上遇到了同样的问题。这是我想出的一个解决方案来设置和模拟我的上下文(而不是模拟我的整个上下文,我只模拟我想要测试的控制器所需的表),以及我之后如何进行。希望对您的问题有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.