Я читал, что с 5-го рельсов мне не нужен database_cleaner. Нужно или нет?
Нет. Это больше не нужно. В предыдущих версиях Rails метод отката транзакций базы данных работал (иногда) только с TestUnit / Minitest и фикстурами.
Я думал, что метод let создает новый объект каждый раз, когда видит переменная. Поскольку у меня есть два контекста, и метод субъекта вызывается в обоих из них, а внутри субъекта у меня есть переменная params, почему объект params не является новым в каждом контексте? (со всеми полями)
Это совершенно неверно.
Используйте let для определения запомнившегося вспомогательного метода. Значение будет кэшировано для нескольких вызовов в одном и том же примере, но не во всех.
Когда вы выполните:
mocked_params = {
min_price: 0,
max_price: 100
}
let(:params) { mocked_params }
Вы действительно просто возвращаете ссылку на объект mocked_params
, а затем изменив этот объект.
Если вы сделаете:
let(:params) do
{
min_price: 0,
max_price: 100
}
end
При первом вызове let
вы получите новый объект ha sh, и значение будет затем кэшироваться, но не делиться между примерами. Но это действительно верхушка айсберга с этой характеристикой c.
describe SomeClass::SomeService, type: :model do
describe '#some_method' do
let(:current_user) { User.create(email: 'name@mail.com') }
# explicit use of subject is a serious code smell!
let(:service) { described_class.new(params, current_user) }
context 'with invalid params' do
# since let is lazy loading we can define it in this context instead
let(:params) do
{
min_price: nil,
max_price: 100
}
end
it 'returns nil if any param is nil' do
# actually call the method under test instead of misusing subject
# this makes it much clearer to readers what you are actually testing
expect(service.some_method).to eq(nil)
end
end
context 'with valid params' do
let(:params) do
{
min_price: 0,
max_price: 100
}
end
it 'returns filtered objects' do
expect(service.some_method).to eq([])
end
end
end
end
Также весьма сомнительно, почему тестируемый объект принимает ha sh в качестве первого позиционного параметра, а не в качестве последнего параметра который является Ruby способом.