Как смоделировать Db соединение в xunit? - PullRequest
0 голосов
/ 18 февраля 2019

Я пишу тестовые случаи в xUnit.Я пишу тестовый блок для открытия соединения с базой данных.Я пишу отрицательный случай, когда база данных не работает.

Ниже приведен реальный код, где я устанавливаю соединение с базой данных.

 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;
      }
    }   

Ниже приведен код моего тестового примера 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");
    }

Может ли кто-нибудь помочь мне написать отрицательный пример модульного теста (когда БД не работает)?Любая помощь будет оценена.Спасибо

1 Ответ

0 голосов
/ 18 февраля 2019

Вы должны придерживаться Разделение интерфейса и Принцип инверсии зависимости с помощью Инверсия управления с помощью Инъекция зависимости .

Таким образом, вы можете создать MockDB2Connection, который вы вставляете в конструктор, в своих модульных тестах, в то время как в своем реальном коде вы передаете правильный DB2Connection.

Предположим, у вас есть сервис, подобный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();
    }
}

Вы можете реализовать классы Mock-соединения следующим образом:

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;
    }
}

Как контейнер IoC, у вас есть несколько вариантов.Microsoft. Microsoft.Extensions.DependencyInjection, AutoFac, CastleWindsor, Ninject и так далее.Выберите тот, который соответствует вашим потребностям.В большинстве случаев, Microsoft или AutoFac должны быть хорошим выбором здесь.

...