Rspec Rails связанная модель-макет не работает после find () - PullRequest
0 голосов
/ 31 августа 2010

У меня есть несколько вложенных моделей, которые требуют немного больше, чем стандартная логика accepts_nested_attributes_for.Вместо того, чтобы автоматически создавать или обновлять дочерние записи на основе ключа идентификатора, в этом случае дочерние записи должны уже существовать и иметь определенные другие условия, или возникает ошибка.

Так что, как часть этого, у меня есть родительский элементМодель итерирует по заданным дочерним атрибутам и вызывает #update_attributes для соответствующих дочерних записей.

Мой вопрос заключается в том, как смоделировать #update_attributes в спецификациях для родительской модели.Я хочу проверить, что дочерние записи, идентифицируемые данными атрибутами, на самом деле являются теми, которые получают #update_attributes

Мой первый подход состоял в том, чтобы попробовать mock_model, что-товот так (не используя фактические названия моделей, а просто «субъект» и «дети» для ясности):

before :each do
  subject.children = mock_model(Child), mock_model(Child), mock_model(Child)
  subject.save!
  @expected = subject.children[1]
  @input = {:child_id => @expected.id, :value => 'something'}
end

it 'should call #update_attributes on the child with given attributes' do
  @expected.should_receive(:update_attributes).
    with({:value => 'something'})
  subject.merge_children_attributes(@input)
end

Однако вы не можете на самом деле сохранять макеты моделей.И вы не можете использовать модели заглушки по той же причине.И мне нужны постоянные записи, так как я использую children.find() или children.all() в реализации.(если я не высмеиваю ассоциацию children, которая кажется неправильной, учитывая, что это метод субъекта).

Итак, я пошел к светильникам.

fixtures :children

before :each do
  subject.children = children(:one), children(:two), children(:three)
  subject.save!
  @expected = subject.children[1]
  @input = {:child_id => @expected.id, :value => 'something'}
end

it 'should call #update_attributes on the child with given attributes' do
  @expected.should_receive(:update_attributes).
    with({:value => 'something'})
  subject.merge_children_attributes(@input)
end

Проблема здесь в том, что ожидаемая совпавшая запись (@expected) никогда не получает :update_attributes - ни с чем.

При большом количестве puts причина этого в том, что когда реализация вызывает children.find(), она возвращает другой экземпляр , чем @expected = subject.children[1] в спецификации.Хотя атрибут: id такой же.ActiveRecord не является идентификационной картой ...

Так как мне написать эту спецификацию для передачи?

ОБНОВЛЕНИЕ

Я подтвердил, просматривая журнал, чтоправильная запись фактически обновляется.Поэтому досадно, что я не могу насмехаться над :update_attributes, потому что идентичность объекта не поддерживается между find с.

1 Ответ

0 голосов
/ 31 августа 2010

Не совсем удовлетворительный ответ, но то, что я сделал, чтобы передать спецификацию, было заглушкой Child.find (что является основным вызовом, когда вы делаете поиск в ассоциации детей) - чтобы вернуть массив ложных детей, которые ямог бы установить ожидания.Итак:

before :each do
  @children = [ mock_model(Child), mock_model(Child), mock_model(Child) ]
  Child.should_receive(:find).and_return(@children)
  @expected= @children[1]
  @input = {:child_id => @expected.id, :value => 'something'}
end

it 'should call #update_attributes on the child with given attributes' do
  @expected.should_receive(:update_attributes).
    with({:value => 'something'})
  subject.merge_children_attributes(@input)
end

Не то, чтобы удовлетворять, потому что ожидание ровно одного children.find(:all) в реализации кажется слишком большим предположением, чтобы добавить его в спецификацию.Маловероятно, но кто скажет, что не может быть реализации, которая вместо этого вызывает несколько children.find() s?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...