Важно ли иметь дело с кэшированием запросов в модульных тестах ActiveRecord? - PullRequest
1 голос
/ 23 февраля 2010

В мире Hibernate у вас часто могут быть модульные тесты, которые, кажется, проходят, но на самом деле есть ошибки, которые не отображаются, потому что вы имеете дело с кэшированными данными. Например, вы можете сохранить родителя с его детьми, думая, что это каскадное сохранение. Если вы повторно запросите родительский объект после сохранения и протестируете размер дочерней коллекции, все выглядит хорошо. Но на самом деле Hibernate не спас детей, а кэшировал родителей, поэтому вы смотрите на не спасенных детей. Один из способов обойти это - очистить кэш сеанса между сохранением и запросом, чтобы вы знали, что данные поступают прямо из базы данных.

Это проблема с ActiveRecord? Если я сохраню модель и затем выполню запрос в том же тесте, возможно ли, что я на самом деле не получаю данные из базы данных, а скорее из кеша запросов? Я не видел ни одного примера тестов, которые бы пытались справиться с этим, поэтому мне интересно, есть ли что-то, что делает это не проблемой?

Ответы [ 2 ]

1 голос
/ 23 февраля 2010

Да. В зависимости от того, как вы пишете свои тесты, кеш запросов Rails может иногда мешать. Иногда rails достаточно умен, чтобы отслеживать, когда кэш должен быть очищен (когда существует очевидная связь между объектами), но вот пример, который не будет вести себя как ожидалось:

user.posts.should == []
Post.create(:user_id => user.id)
user.posts.size.should_not == [] # Fails, since the original query was cached.

В общем, если вы выполняете один и тот же запрос дважды в одном и том же тесте, вы должны вызвать .reload для данных перед попыткой выполнить второй запрос. Вот так:

user.posts.should == []
Post.create(:user_id => user.id)
user.posts.reload
user.posts.size.should_not == []

По моему личному опыту, лучше рассмотреть другой способ написания теста, чем использовать метод, описанный выше. Например, вот лучший способ написания вышеупомянутого, который не будет затронут кешем запросов:

lambda { Post.create(:user_id => user.id) }.should_change(user.posts, :count).by(1)

0 голосов
/ 23 февраля 2010

Я никогда не сталкивался с этой проблемой как с ActiveRecord. Насколько я понимаю, кеш только для чтения, поэтому сохранение всегда выполняется.

...