Вопрос по ruby – Как утверждать, что определенный метод вызывается с Ruby Minitest Framework?

25

Я хочу проверить, правильно ли функция вызывает другие функции с помощью minitest Ruby, но я не могу найти подходящийassert проверить издоктор.

The source code
class SomeClass
  def invoke_function(name)
    name == "right" ? right () : wrong ()
  end

  def right
    #...
  end

  def wrong
    #...
  end
end
The test code:
describe SomeClass do
  it "should invoke right function" do
    # assert right() is called
  end

  it "should invoke other function" do
    # assert wrong() is called
  end
end

Ваш Ответ

3   ответа
23

С минитест вы используетеexpect метод, чтобы установить ожидание для метода, который будет вызван на фиктивном объекте, как так

obj = MiniTest::Mock.new
obj.expect :right

Если вы хотите установить ожидание с параметрами и возвращаемыми значениями, то:

obj.expect :right, return_value, parameters

А для конкретного объекта вот так:

obj = SomeClass.new
assert_send([obj, :right, *parameters])
Я думаю, что использование assert_send не является безопасным выбором. в соответствии с документами:ruby-doc.org/stdlib-2.0.0/libdoc/minitest/rdoc/MiniTest/…
Для конкретной версии объекта естьmust_send для при использованииminitest/spec
Скажите, если я что-то упустил, но я думаю, что ответ @ jing-li ниже является правильным, если упомянуть, чтоassert_send здесь не подходит. ОП хочет проверить этоright называется когдаinvoke_function называется. Дополнительно,obj.verify необходимо для обеспеченияright вызывается на фиктивном объекте в первой части этого ответа. Всем, кто читает это, убедитесь, что ваши тесты не пройдены, прежде чем их сдавать.
Можете ли вы привести свой пример, когда этоinvoke_function называется?
3

Согласно приведенному примеру, нет другого класса делегата, и вы хотите убедиться, что метод вызывается правильно из того же класса. Тогда приведенный ниже фрагмент кода должен работать:

class SomeTest < Minitest::Test
  def setup
    @obj = SomeClass.new
  end

  def test_right_method_is_called
    @obj.stub :right, true do
      @obj.stub :wrong, false do
        assert(@obj.invoke_function('right'))
      end
    end
  end

  def test_wrong_method_is_called
    @obj.stub :right, false do
      @obj.stub :wrong, true do
        assert(@obj.invoke_function('other'))
      end
    end
  end
end

Идея заглушки[method_expect_to_be_called] вернув простойtrue значение, и в блоке-заглушке утверждают, что он действительно вызывается и возвращаетtrue значение. Заглушить другой неожиданный метод означает просто убедиться, что он не вызывается.

Примечание: assert_send не будет работать правильно. Пожалуйста, обратитесь кофициальный документ.

Фактически, нижеследующее утверждение пройдет, но не означает, что оно работает так, как ожидалось:

assert_send([obj, :invoke_function, 'right'])
# it's just calling invoke_function method, but not verifying any method is being called
14

Минитест имеет специальный.expect :call для проверки, если какой-то метод вызывается.

describe SomeClass do
  it "should invoke right function" do
    mocked_method = MiniTest::Mock.new
    mocked_method.expect :call, return_value, []
    some_instance = SomeClass.new
    some_instance.stub :right, mocked_method do
      some_instance.invoke_function("right")
    end
    mocked_method.verify
  end
end

К сожалению, эта функция не очень хорошо задокументирована. Я узнал об этом отсюда:https://github.com/seattlerb/minitest/issues/216

Похожие вопросы