Модульный тест для NpgsqlCommand с Rhino Mocks - PullRequest
1 голос
/ 16 марта 2010

Мой модульный тест продолжает получать следующую ошибку: «System.InvalidOperationException: Соединение не открыто.»

Тест

[TestFixture]
public class Test
{
   [Test]
    public void Test1()
    {
        NpgsqlConnection connection = MockRepository.GenerateStub<NpgsqlConnection>();

        // Tried to fake the open connection
        connection.Stub(x => x.State).Return(ConnectionState.Open);
        connection.Stub(x => x.FullState).Return(ConnectionState.Open);

        DbQueries queries = new DbQueries(connection);

        bool procedure = queries.ExecutePreProcedure("201003");

        Assert.IsTrue(procedure);
    }
}

проверяемый код

using System.Data;
using Npgsql;

public class DbQueries
{
    private readonly NpgsqlConnection _connection;

    public DbQueries(NpgsqlConnection connection)
    {
        _connection = connection;
    }

    public bool ExecutePreProcedure(string date)
    {
        var command = new NpgsqlCommand("name_of_procedure", _connection);
        command.CommandType = CommandType.StoredProcedure;

        NpgsqlParameter parameter = new NpgsqlParameter {DbType = DbType.String, Value = date};

        command.Parameters.Add(parameter);
        command.ExecuteScalar();

        return true;
    }
 }

Как бы вы протестировали код, используя Rhino Mocks 3.6?

PS. NpgsqlConnection - это соединение с сервером PostgreSQL.

1 Ответ

1 голос
/ 17 марта 2010

Есть несколько проблем с вашим подходом:

  1. NpgsqlConnection - это класс, и я предполагаю, что свойства состояния не являются виртуальными - поэтому созданная заглушка просто не будет работать (как вы заметили0. Я не думаю, что есть обходной путь.
  2. В своем тесте вы действительно тестируете внутренние компоненты NpgsqlCommand (потому что вы создаете конкретную реализацию в методе ExecuteProcedure). Это сторонний класс, и вы должны предполагать только что-либо о его документированном интерфейсе, а не подробности реализации (например, что он использует свойство State для соединения)

Так что мой подход заключается в том, чтобы не запускать какие-либо модульные тесты для этого класса, потому что он фактически является просто оболочкой сторонней библиотеки. Вместо этого перейдите на интеграционные тесты (поэтому создайте тестовую базу данных и подключитесь к ней).

...