Проверяет ли rSpec, может ли объект быть создан? - PullRequest
0 голосов
/ 20 октября 2011

Я чрезвычайно новичок в rspec и пытаюсь написать тест, чтобы убедиться, что созданный объект действительно существует. Вот как выглядит мой тест сейчас:

require 'spec_helper'

describe "UserService" do
  describe ".new" do
    it "should create a UserService object" do
      service = UserService.new
      service.should_not be_nil
    end
  end
end

Проблема в том, что я получаю этот вывод при запуске теста:

  1) UserService.new should create a UserService object
     Failure/Error: service = UserService.new
     Errno::ECONNREFUSED:
       Connection refused - connect(2)
     # ./spec/requests/user_service_spec.rb:6:in `new'
     # ./spec/requests/user_service_spec.rb:6:in `block (3 levels) in <top (required)>'

Я ожидаю, что в этот момент будет отказано в соединении, но как я могу проверить это вместо того, чтобы прервать его? Или, что я вижу правильный вывод? Спасибо!

1 Ответ

1 голос
/ 06 февраля 2013

Я вижу две проблемы с этим.Сначала вы пытаетесь подключиться к внешней службе в тесте.Как правило, вы хотите передать объекту тестирования какой-то макет, представляющий службу, к которой вы обычно подключаетесь.Я предполагаю по тому, что у вас есть в вашем вопросе и в комментариях, что вашему коду потребуются следующие изменения, чтобы это работало:

Вам нужно построить фасад или прокси-объект, чтобы «скрыть»реальный сервис из вашего объекта UserService.Этот объект должен просто отображать базовый сервис один-к-одному.Причина этого в том, что вы не хотите, чтобы наши внутренние компоненты были тесно связаны с внешним сервисом, вы хотите, чтобы они были связаны с вашими объектами (и никогда не были тесно связаны).Фасад не должен подвергаться модульному тестированию, что вернет вас туда, где вы сейчас находитесь, и не должен проходить модульное тестирование, поскольку он не содержит никакой бизнес-логики.

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

Во-вторых, вы использовали should_not raise_error, чтобы игнорировать конкретный случай в вашем тесте.Можно использовать его с указанной ошибкой, например, should_not raise_error(ConnectionError), но выбрасывание ошибок - это обычное дело, когда вы не можете спасти себя, и ваш тест будет прерван, если не произойдет, если вы позже добавите это поведение.

В тесте говорится, что вы должны получить объект UserService при вызове UserService.new(), в нем ничего не говорится о том, чтобы не получить его обратно, если ... Что вы должны сделать, чтобы правильно протестировать в этом случае и документировать ожидаемое поведение, этонакорми его рабочим макетом в тесте, который у тебя сейчас есть, и создай второй тест, например:

describe ".new" do
  it "when service is down should throw error" do
    UserService.new(offline_mock).should raise_error(ConnectionError)
  end
end

Несколько мыслей о том, как не оказаться в этой ситуации для начала;) Как обычно, проблема втестирование обычно является признаком архитектурной проблемы.

...