2015-08-30 4 views
0

У меня есть метод типа update, который я пытаюсь протестировать в Rails с помощью MiniTest и FactoryGirl. Моя проблема в том, что хотя я вижу, что обновление происходит правильно в функции, оно, похоже, не вернулось обратно в тестовую функцию.Запись базы данных не сохраняется/сохраняется в функции проверки Rails?

Это является объекты, которые мы работаем с, (obj дается по умолчанию location начать с:

location1 = create :location 
location2 = create :location 
obj = create :object, location: location1 

И тогда мы называем функцию update, которая принимает id «S:

obj.update_location(obj.id, location2.id) 

update функция:

def update_location(obj_id, loc_id) 
    @obj = Object.find(obj_id) 
    @obj.location_id = loc_id 
    @obj.save 
end 

Но когда, вернувшись в тестовый файл, я пытаюсь assert изменением ...

assert_equal obj.location_id, location2.id 

... Я получаю отказ. Консоль сообщает мне, что obj.location_id по-прежнему равен location1.id! Почему это?

Кажется, что @obj.saveявляется работает должным образом, потому что я вставил puts @obj.inspect в обновление-функции и выводит правильно обновленный location_id.

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

В заключение, мой вопрос: Почему мое обновление не сохраняется в рельсах MiniTest test функция?

EDIT: Вот весь тест:

test "update_location" do  
    location1 = create :location 
    location2 = create :location 

    #give the obj a starting `type` 
    obj = create :obj, location: location1 

    obj.update_location(obj.id, location2.id) 
    assert_equal obj.location_id, location2.id  
end 
+0

Думаю, нам нужно будет увидеть весь цикл испытаний, прежде чем сможете подумать об этом разумным способом. Я также попробую «сэкономить!», Чтобы избежать употребления исключений. –

+0

Я добавил целую и только тестовую функцию в файл. Я запускаю только этот файл, используя 'rake test test/models/obj_test.rb' –

+0

(@ DaveNewton-Tried' save! ', Не помогло ...) –

ответ

0

Проблема решена, и вот мое понимание:

Вопрос был в том, как ОРМ работы рельсов. Исходный объект «obj» загружается данными из БД при его создании ... но последующие изменения в БД не сохраняются автоматически до obj.Я думал, что obj.some_attribute смотрит на базу данных для записи obj, чтобы найти значение атрибута - но на самом деле я думаю, что атрибуты просто загружаются в переменную при ее создании, а база данных НЕ обращается, если я вызываю obj.some_attribute на более поздний момент времени.

Обычно, когда обновление выполняется через переменную, Rails знает, как обновить переменную для вас. Поэтому, когда вы пишете obj.some_attribute = 5, а затем позже напишите obj.some_attribute, Rails знает, что значение должно быть равно 5. Но эта магия Rails не возникает в этой ситуации, потому что она не обновляет запись через переменную.

Так что нужно сделать просто reload объект из базы данных.

So assert_equal obj.reload.location_id, location2.id работ!

0

2 вопросов, которые могут помочь вам найти ответ:

  1. Почему вы используете экземпляр переменной @obj вместо локальной переменной obj

  2. Почему у вас есть специальный метод для обновления 1 колонки. Будет ли update_column не работать для вас?

+0

Tnx за помощью! Вот ответы на ваши вопросы ... 1-Не знаете, почему это было использовано, но обратите внимание, что он находится в отдельном файле из тестов (он находится в 'app/models/objects.rb'). 2-Это действительно часть более крупного метода, который делает больше вещей, я просто упростил его для SO ...: P –

+0

(Я пытался переключиться с '@ obj' на просто' obj', безрезультатно). –

 Смежные вопросы

  • Нет связанных вопросов^_^