TL; DR Я хотел бы знать, если я могу проверить методы модели, которые используют запрашивая (т.е. find
, where
) без сохраняющиеся объектов испытаний в базе данных.рельсы Модульное тестирование с ActiveRecord ассоциаций без удара DB
Итак, я новичок в рельсах и работаю над существующей кодовой базой.
Одна вещь, которую я заметил, это то, что наши модульные тесты принимают навсегда для запуска.
При расследовании виновником было, конечно же, что мы сохраняем все до БД, когда мы тестируем наши модели.
Итак, я решил попробовать моделировать тесты, которые не попадают в БД, но я столкнулся с проблемой:
Когда модель имеет связь с другими моделями, любые операции, выполняемые на ней, предполагают что все сохраняется.
Давайте посмотрим на ПРИМЕР-
class Parent < ActiveRecord::Base
has_many :children, dependent: :destroy
def default_child
children.find_by(default: true)
end
end
Поэтому, естественно, я хочу, чтобы проверить, что мой default_child
метод работает:
parent = Parent.new
default_child = parent.children.build(default: true)
assert_equal default_child, parent.default_child
, но этот тест не удается, так как фактический результат parent.default_child
есть nil
!
Это связано с тем, что внутри метода default_child
используется find_by
, который, кажется, работает только в контексте сохраняемых объектов.
Так что я вынужден написать тест, как SO-
parent = Parent.new
# I don't want to do this!!
parent.save
# why 'create' and not 'build'?
default_child = parent.children.create(default: true)
assert_equal default_child, parent.default_child
Что уродливее и медленнее.
Есть ли способ проверить эти операции в памяти?
Я пробовал установить children
вручную (parent.children = [ child1, child2 ]
).
Это не вызывает ошибку, но мне кажется, что find_by
не смотрит туда, а в БД ...
я вижу, что a similar question пришел 3-х лет назад, без окончательного ответа, я интересно, изменилось ли что-то с тех пор.
PS бонусный вопрос - что я могу сделать для валидаций, которые являются on: update
? похоже, что я должен упорствовать в тестовом объекте хотя бы один раз, прежде чем они будут вызваны.
Да, это то, что я думал. Я мог бы пойти и посмотреть на насмешливый ActiveRecord, хотя я не очень в восторге от этой перспективы. Кстати, мой последний вопрос касался утверждений, которые являются 'on: update', поэтому ваш ответ не будет работать в этом случае (сначала нужно сохранить« родительский »). –