简体   繁体   English

如何在 xunit 中模拟 Db 连接?

[英]How to mock Db connection in xunit?

I am writing unit test cases in xUnit.我正在 xUnit 中编写单元测试用例。 I am writing unit test case for opening database connection.我正在编写用于打开数据库连接的单元测试用例。 I am writing negative case when database is down.当数据库关闭时,我正在写负面案例。

Below is the real code where I am making connection to database.下面是我连接到数据库的真实代码。

 public IDbConnection CreateDirectDb2Connection(int attempt = 0)
    {
      try
      {
        var conn = new DB2Connection(BuildDB2ConnectionString());
        conn.Open();
        return conn;
      }
      catch (Exception ex)
      {
        logService.Debug($"Failed to create and open a connection, attempt {attempt + 1}/3, error: {ex}");
        if (attempt < 2)
        {
          // Retry twice
          return CreateDirectDb2Connection(attempt + 1);
        }

        throw ex;
      }
    }   

Below is my xUnit test case code.下面是我的 xUnit 测试用例代码。

 public class ContextProviderServiceTests
    {
    private readonly IContextProviderService contextProvider = Substitute.For<IContextProviderService>();
    private readonly IDbCommand db2Command;
    private readonly MainframeDirectAccessRepository mainframeRepository;
    private readonly IDbConnection db2Connection;
      public ContextProviderServiceTests()
       {
          db2Connection = Substitute.For<IDbConnection>();
      db2Command = Substitute.For<IDbCommand>();
      db2Command.Parameters.Returns(Substitute.For<IDataParameterCollection>());
      db2Command.CreateParameter().Returns(Substitute.For<IDbDataParameter>());

      commandParameters = new List<TestDataParameter>();
      db2Command.Parameters.When(x => x.Add(Arg.Any<object>()))
        .Do(c => commandParameters.Add(new TestDataParameter
          {
            Name = c.Arg<IDbDataParameter>().ParameterName,
            Value = c.Arg<IDbDataParameter>().Value,
            DbType = c.Arg<IDbDataParameter>().DbType
          }));
     }
    [Fact]
    public void CreateDirectDb2ConnectionFailure()
    {
      var connection = mockProvider.GetDependency<IContextProviderService();
      connection.CreateDirectDb2Connection().Returns("I am not sure what to 
      return here");
    }

Can someone help me to write negative unit test case(When DB is down)?有人可以帮我写负面的单元测试用例吗(当数据库关闭时)? Any help would be appreciated.任何帮助,将不胜感激。 Thanks谢谢

You should adhere to Interface Segregation and Dependency Inversion principle by using Inversion of Control with the help of Dependency Injection .您应该在依赖注入的帮助下使用控制反转来遵守 接口隔离依赖倒置原则

This way, you can create a MockDB2Connection, which you inject into the constructor, in your unit tests, while in your real code, you pass a proper DB2Connection.这样,您可以在单元测试中创建一个 MockDB2Connection,将其注入到构造函数中,而在您的实际代码中,您传递一个正确的 DB2Connection。

Assume you have a service like this:假设您有这样的服务:

public class SomeService
{
    private readonly IDbConnection _dbCOnnection;

    public SomeService(IDbConnection dbConnection)
    {
        _dbCOnnection = dbConnection;
    }

    public async Task<IEnumerable<Foo>> GetFoos()
    {
        // Obviously don't do this in production code;
        // just for demonstration purposes.
        await _dbCOnnection.OpenAsync();
    }
}

You can implement Mock-connection classes like this:您可以像这样实现模拟连接类:

public interface IDbConnection
{
    Task OpenAsync();

    // Other required methods...
}

public class ThrowingDbConnection : IDbConnection
{
    public Task OpenAsync()
    {
        throw new Exception("...");
    }
}

public class FakeDbConnection : IDbConnection
{
    public Task OpenAsync()
    {
        return Task.CompletedTask;
    }
}

As IoC container, you have multiple choices.作为 IoC 容器,您有多种选择。 Microsoft's Microsoft.Extensions.DependencyInjection, AutoFac, CastleWindsor, Ninject and so on.微软的 Microsoft.Extensions.DependencyInjection、AutoFac、CastleWindsor、Ninject 等。 Pick the one that suits your needs.选择一款适合您的需求。 Most of the cases, Microsoft's or AutoFac should be good choices here.大多数情况下,Microsoft 或 AutoFac 在这里应该是不错的选择。

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

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