Устаревание RSpec any_instance: как это исправить?

#ruby-on-rails #ruby #testing #rspec

#ruby-on-rails #ruby #тестирование #rspec

Вопрос:

В моем проекте Rails я использую rspec-mocks с использованием any_instance, но я хочу избежать этого сообщения об устаревании:

Using any_instance from rspec-mocks' old :should syntax without explicitly enabling the syntax is deprecated. Use the new :expect syntax or explicitly enable :should instead.

Вот мои спецификации:

 describe (".create") do
  it 'should return error when...' do
    User.any_instance.stub(:save).and_return(false)
    post :create, user: {name: "foo", surname: "bar"}, format: :json
    expect(response.status).to eq(422)
  end
end
  

Вот мой контроллер:

 def create
    @user = User.create(user_params)
    if @user.save
      render json: @user, status: :created, location: @user
    else
      render json: @user.errors, status: :unprocessable_entity
    end
end
  

Я хотел бы использовать синтаксис new:expect, но я не могу найти, как его правильно использовать.

Я использую RSpec 3.0.2.

Комментарии:

1. какая у вас версия Rspec?

Ответ №1:

Используйте allow_any_instance_of :

 describe (".create") do
  it 'returns error when...' do
    allow_any_instance_of(User).to receive(:save).and_return(false)
    post :create, user: {name: "foo", surname: "bar"}, format: :json
    expect(response.status).to eq(422)
  end
end
  

Комментарии:

1. Работает отлично!

2. И теперь он allow_any_instance_of также помечен как устаревший . Есть другое решение?

3. @AlexisWilke — насколько я понимаю — теперь это считается недостатком дизайна — ожидается, что вы разработаете свой сервис таким образом, чтобы вам не нужно было заглушать «любой экземпляр», но вместо этого стремиться заглушать конкретные экземпляры…

Ответ №2:

Я могу воспроизвести это :

В моем файле test.rb :-

 #!/usr/bin/env ruby

class Foo
  def baz
    11
  end
end
  

В моем файле test_spec.rb

 require_relative "../test.rb"

describe Foo do
  it "invokes #baz" do
    Foo.any_instance.stub(:baz).and_return(20)
    expect(subject.baz).to eq(20)
  end
end
  

Теперь, если я его запущу :-

 arup@linux-wzza:~/Ruby> rspec
.

Deprecation Warnings:

Using `any_instance` from rspec-mocks' old `:should` syntax without explicitly enabling the syntax is deprecated. Use the new `:expect` syntax or explicitly enable `:should` instead. Called from /home/arup/Ruby/spec/test_spec.rb:4:in `block (2 levels) in <top (required)>'.
  

Теперь я нашел список изменений

allow(Klass.any_instance) и expect(Klass.any_instance) теперь выведите предупреждение. Обычно это ошибка, и пользователи обычно хотят вместо этого allow_any_instance_of или expect_any_instance_of . (Сэм Фиппен)

Я меняю test_spec.rb , как показано ниже :

 require_relative "../test.rb"

describe Foo do
  it "invokes #baz" do
    expect_any_instance_of(Foo).to receive(:baz).and_return(20)
    expect(subject.baz).to eq(20)
  end
end
  

и это работает отлично :-

 arup@linux-wzza:~/Ruby> rspec
.

Finished in 0.01652 seconds (files took 0.74285 seconds to load)
1 example, 0 failures
arup@linux-wzza:~/Ruby>