idbcontexttransaction 的 NUNIT 测试用例

问题描述 投票:0回答:1
I am writing  Nunit test case for the below. Here the IDbContextTransaction is from the Microsoft.EntityFrameworkCore.Storage library. Here the argument of DeleteDataAsync transaction is beling passed from the caller method and in the caller method it is written like using (var scope = _dbContext.Database.BeginTransaction()) this is being passed to this method.

我在调试系统不支持异常时收到以下错误。 不支持的表达式。GetDbTransaction .

public async Task DeleteDataAsync(IDbContextTransaction transaction)
{
    try
    {
        using (var command = transaction.GetDbTransaction().Connection.CreateCommand())
        {

            await TruncateTable(command, $"TRUNCATE TABLE MY_TABLE");
            
        }
    }
    catch (Exception ex)
    {
        transaction.Rollback();
        _logger.LogCritical($"Error occurred in DeleteDataAsync(): {ex.Message}");
    }
}

I am trying to write unit test case to cover the Delete data async method. Here i am trying to mock the transaction. 

 [Test]
 public async Task DeleteDataAsync_Error()
 {

     var transactionMock = new Mock<IDbContextTransaction>();
     var dbTransactionMock = new Mock<DbTransaction>();
     var dbCommandMock = new Mock<DbCommand>();

     **transactionMock.Setup(t => t.GetDbTransaction())
                           .Returns(dbTransactionMock.Object);**

     dbTransactionMock.Setup(t => t.Connection.CreateCommand())
                      .Returns(dbCommandMock.Object);

 }
Extension methods (here: DbContextTransactionExtensions.GetDbTransaction) may not be used in setup / verification expressions. May i know what is wrong here while mocking

我无法弄清楚如何解决,我确信我编写的以下单元测试需要修改。有人可以帮我吗?

asp.net-core .net-core c#-4.0 nunit
1个回答
0
投票

我假设您有一个存储库层,并且此方法

DeleteDataAsync
是从外部用例或服务调用的。我建议您管理上层(服务或用例)中的所有事务状态,并且不要将其作为参数传递给存储库方法。

这样,您将拥有一个更加结构化的项目,具有正确定义的角色,更易于理解,并且您将能够仅测试存储库层的数据库命令

或者,如果您的项目中没有单独的层,只需管理调用此方法的外部方法中的所有事务

DeleteDataAsync
,并使其独占以执行查询。例如这样的事情:

public async Task RandomOutsideMethod()
{
    try
    {
        ...rest of your code that have the transaction declared

        using (var command = transaction.GetDbTransaction().Connection.CreateCommand())
        {
            await DeleteDataAsync();
        }
    }
    catch (Exception ex)
    {
        transaction.Rollback();
        _logger.LogCritical($"Error occurred in RandomOutsideMethod(): {ex.Message}");
    }
}

public async Task DeleteDataAsync()
{
    try
    {
        await TruncateTable(command, $"TRUNCATE TABLE MY_TABLE");
    }
    catch (Exception ex)
    {
        _logger.LogCritical($"Error occurred in DeleteDataAsync(): {ex.Message}");
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.