使用NUnit模拟EF的ExecuteSqlCommand

问题描述 投票:3回答:2

我正在使用实体框架核心。我指的是这里建议的代码之一:https://stackoverflow.com/a/41515103/9766215

public void SaveOrUpdate(MyEntity entity)
{
    var sql =  @"MERGE INTO MyEntity
                USING 
                (
                   SELECT   @id as Id
                            @myField AS MyField
                ) AS entity
                ON  MyEntity.Id = entity.Id
                WHEN MATCHED THEN
                    UPDATE 
                    SET     Id = @id
                            MyField = @myField
                WHEN NOT MATCHED THEN
                    INSERT (Id, MyField)
                    VALUES (@Id, @myField);"

    object[] parameters = {
        new SqlParameter("@id", entity.Id),
        new SqlParameter("@myField", entity.myField)
    };
    context.Database.ExecuteSqlCommand(sql, parameters);
}

我需要模拟ExecuteSqlCommand,但是Moq设置不允许覆盖此扩展方法。我不想模拟整个方法SaveOrUpdate。请提出是否可以使用任何数据库上下文方法模拟或设置它以进行单元测试。我正在使用UseInMemoryDatabase进行数据库上下文的单元测试。

c# unit-testing asp.net-core entity-framework-core dbcontext
2个回答
2
投票
您将需要模拟您的方法而不是EF核心实现。您可以将您的Mehtod虚拟化并通过Moq来模拟其实现:

public virtual void SaveOrUpdate(MyEntity entity) { var sql = @"MERGE INTO MyEntity USING ( SELECT @id as Id @myField AS MyField ) AS entity ON MyEntity.Id = entity.Id WHEN MATCHED THEN UPDATE SET Id = @id MyField = @myField WHEN NOT MATCHED THEN INSERT (Id, MyField) VALUES (@Id, @myField);" object[] parameters = { new SqlParameter("@id", entity.Id), new SqlParameter("@myField", entity.myField) }; context.Database.ExecuteSqlCommand(sql, parameters); }

然后模拟此方法的实现。

[查看以下帖子:

https://entityframework.net/knowledge-base/26014969/how-to-moq-entity-framework-sqlquery-calls

How to Moq Entity Framework SqlQuery calls


0
投票
我真的很喜欢这里的建议:Moq Entity Frameworks ExecuteSQLCommand。通过在上下文中添加包装器,实际上并不是在模拟整个函数,而是在ExecuteSqlCommand上。

所以在您的上下文类中

public class MyContext : DbContext { public virtual int ExecuteSqlCommand(string sql, params object[] parameters) { return Database.ExecuteSqlCommand(sql, parameters); } public virtual int ExecuteSqlCommand(TransactionalBehavior transactionalBehavior, string sql, params object[] parameters) { return Database.ExecuteSqlCommand(transactionalBehavior, sql, parameters); } // The rest of the implementation

因此,您现在可以模拟上下文,并且由于函数是虚拟的,因此您也可以模拟它们。您只需要像这样更改代码:

public void SaveOrUpdate(MyEntity entity) { var sql = @"MERGE INTO MyEntity USING ( SELECT @id as Id @myField AS MyField ) AS entity ON MyEntity.Id = entity.Id WHEN MATCHED THEN UPDATE SET Id = @id MyField = @myField WHEN NOT MATCHED THEN INSERT (Id, MyField) VALUES (@Id, @myField);" object[] parameters = { new SqlParameter("@id", entity.Id), new SqlParameter("@myField", entity.myField) }; context.ExecuteSqlCommand(sql, parameters); }

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