Методы юнит-тестирования Ruby, Mocking и Stubbing - PullRequest
3 голосов
/ 11 декабря 2011

Меня завербовали в качестве разработчика ПО, и я пытаюсь попасть в модульное тестирование с RSPEC и RR в ruby, но мне сложно выбрать конкретную стратегию, главным образом потому, что мне поручили писать модульные тесты в кодкоторый уже написан.

Рассмотрим следующий код, который является частью большого метода с именем method1:

  if (["5234541252", "6236253223"].include?(self.id))
    self.DoCheck
    logs.add 'Doing check', "id = #{self.id}"
    return
  end

Соответствующий модульный тест для этой части метода был бы чем-токак:

"should do check only if id = 5234541252 or 6236253223"

Но я сталкиваюсь с несколькими вопросами, в основном касающимися лучших практик, например:

Как я могу проверить, был ли вызван DoCheckиз "method1" с использованием RR и RSPEC?

Я пытался использовать dont_allow (Object) .DoCheck, но он не будет работать.

describe :do_route do
  it "should do check only if id = 5234541252 or 6236253223" do
  user = Factory(:User)
  user.id = "5234541252"

  dont_allow(user).DoCheck
  user.method1
end

Есть ли другой способ сделать выводесли "DoCheck" был вызван или нет?

1 Ответ

0 голосов
/ 11 декабря 2011

Вы можете использовать технику «Частичное копирование» на тестируемом объекте. Это означает, что вам нужно установить ожидание, что user.method1 отправит сообщение DoCheck на user. RSpec может установить это ожидание с помощью метода should_receive(). Тест не пройден, если ожидание не будет выполнено.

Попробуйте следующий код:

describe :do_route do
  it "should do check if id = 5234541252 or 6236253223" do
    user = Factory(:User)
    user.id = "5234541252"

    user.should_receive(:DoCheck) # set expectation that DoCheck will be called

    user.method1  # execute
  end
end

При RR это ожидание может выглядеть следующим образом:

describe :do_route do
  it "should do check if id = 5234541252 or 6236253223" do
    user = Factory(:User)
    user.id = "5234541252"

    mock(user).DoCheck # set expectation that DoCheck will be called

    user.method1  # execute
  end
end

Обновление

Но будьте осторожны с использованием фиктивных объектов и частичных имитаций, потому что они делают ваш тестовый код тесно связанным с текущим поведением тестируемого кода. Если вы собираетесь провести рефакторинг этого кода в будущем, вы, вероятно, получите множество неудачных тестов (тех, которые используют фиктивные выражения). Попробуйте протестировать код без макетов (ввод-вывод) и используйте макеты только в том случае, если они четко объясняют назначение тестируемого класса. Когда вы пишете тест с использованием mock, всегда спрашивайте себя: нужно ли вам утверждать, что этот метод вызывает другой метод, или что вас действительно волнует, так это вывод метода или что-то еще.

Надеюсь, это поможет!

...