Действительно ли возможно проверить метод класса с MiniTest (например, Foo.bar)?

Как я могу проверить тот , Foo.bar называют в следующем примере, не проверяя поведение бар метод (который уже проверен в другом месте)?

# Code
class Alpha
  def process
    Foo.bar
  end
end

Следующая спекуляция - то, что я имею до сих пор. К сожалению, этот подход уже бросает "класс определенное" предупреждение, так как Фу был уже определен в другом месте в моем проекте.

 # Spec
 let(:alpha) { Alpha.new }
 let(:klass) { MiniTest::Mock.new }

 subject { alpha.process }

 it "calls Foo.bar" do
   klass.expect(:bar, '')     # Define method call expectation
   Foo = klass                # Redefine Foo as a mock object
   subject                    # Run method being tested
   klass.verify               # Confirm method was called
 end

я не хочу, чтобы мой тест зависел от Фу класс, так как это - внешняя зависимость, и я не хочу проверять ценность ответа Foo.bar , так как это может измениться произвольно.

3
nl ja de

2 ответы

Чтобы дразнить класс как это, необходимо вставить пункт инъекции как так:

class Alpha
  def initialize(opts = {})
    @foo_class = opts[:foo_class] || Foo
  end

  def process
    @foo_class.bar
  end
end

Это работает, потому что имя класса - просто константа в Руби, которая может быть назначена как любая другая стоимость. Так, а не жесткое кодирование требование к Фу класс в Альфа , вы теперь называете метод на том, на что ваше новое @foo_class указывает переменная экземпляра. Большую часть времени это все еще будет классом Фу , если вы не пройдете в чем-то еще. Я обычно скрываю ложные параметры как это как дополнительный params, как я сделал здесь. Я также не включаю ссылки на них в предназначенной документации конечного пользователя, потому что они - технически не часть того, что я считаю общественным API.

Тогда в вашем тесте, можно инициализировать ваш Альфа объект как так:

fooClassMock = MiniTest::Mock.new
fooClassMock.expect(:bar, '')
alpha = Alpha.new(:foo_class => fooClassMock)

И необходимо получить результаты, которые вы ищете.

6
добавлено
@user1955626 На самом деле, вместо того, чтобы ожидать : новый , я полагаю, что необходимо ожидать, <закодируйте>: инициализируйте . Возвращаемое значение инициализирует должен быть другим Насмешка , который ожидает, <закодируйте>: бар и прибыль соответствующая стоимость. Но ли это ожидает, <закодируйте>: новый или : инициализируйте , ключ должен возвратить другой Насмешка , который ожидает, <закодируйте>: бар .
добавлено автор Lee, источник
Это добирается, жаждут комментариев, не стесняйтесь открывать вопрос на нем и I' ll отвечают на него там где я don' у t есть только 500 знаков, и я могу дать вам подчеркнутый синтаксисом ответ.
добавлено автор Lee, источник
Правильный, действительно. Что, если мой метод "процесса" (согласно вашему примеру выше) должен сделать @foo_class.new.bar? Который должен быть, мой ожидает? fooClassMock.expect (: бар, ' ') it' легкий s, но другой должен быть fooClassMock.expect (: новый, Фу) или что-то еще? I' m не способный дразнить что-то вроде этого. Какой-либо намек?
добавлено автор Marco Bresciani, источник
Хорошо на epecting : инициализируйте . Что относительно возвращенного результата? Если это fooClassMock.expect (: инициализируйте, the_other_mock.class) или fooClasssMock.expect (: инициализируйте, the_other_mock.new) или что-то как этот? Очевидно, написавший новую насмешку как the_other_moc = MiniTest:: Mock.new и определенное ожидание по <коду>: бар метод.
добавлено автор Marco Bresciani, источник

Я знаю, что это - что-то вроде старого вопроса, но я искал решение для этого, которое не потребовало, чтобы код бизнеса изменения сделал тесты легче, и я думаю, что предложил решение.

Даже если вы используете Рельсы, необходимо добавить драгоценный камень "мини-тест" к вашему Gemfile , то добавляют , требуют "мини-теста/насмешки" к вашему test_helper.rb .

it "calls Foo.bar" do
  bar_is_called = false
  bar_lambda = ->{
    bar_is_called = true
  }

  Foo.stub(:bar, bar_lambda) do
    Alpha.new.process
  end
  bar_is_called.must_equal true
end

.stub can be passed a return value, or when passed something that responds to .call, it calls .call on it (Docs for the stub method). In this example. bar_lambda is called, changing the value of bar_is_called. This verifies that Foo.bar was called.

Это также работает так же в испытательном синтаксисе:

test 'Foo.bar is called' do
  bar_is_called = false
  bar_lambda = ->{
    bar_is_called = true
  }

  Foo.stub(:bar, bar_lambda) do
    Alpha.new.process
  end
  assert bar_is_called
end
2
добавлено
pro.ruby
pro.ruby
1 181 участник(ов)

Язык программирования Ruby Additional docs: https://rubyreferences.github.io/rubyref/ Invite: https://telegram.me/joinchat/Be4rsT2NuB3CyJaF26j1kA Кто хочет компилировать: @crystal_ru (его синтаксис основан на Ruby) Участник @proDOT

Ruby, Rails, Hanami | dry-rb
Ruby, Rails, Hanami | dry-rb
1 180 участник(ов)

https://telegram.me/rubyjob - Ruby Job По вопросам - @eugene_shved

Ruby School .us
Ruby School .us
1 045 участник(ов)

Чат-болталка для учеников руби-школы и не только. Правила: https://telegra.ph/Pravila-chata-Rubi-shkoly-03-13

Random Ruby Chat
Random Ruby Chat
589 участник(ов)

Правила публикации вакансий: https://t.me/codenamecrud/60865

Rubyata
Rubyata
333 участник(ов)

Коммюнити Ruby и Ruby On Rails Флуд не приветствуются. Вакансии можно публиковать только и ТОЛЬКО по пятницам с хештегом #вакансия.

Ruby Talks
Ruby Talks
236 участник(ов)

Национальная Флеймотека

RubyRush
RubyRush
189 участник(ов)

rubyrush.ru программирование для самых новичков