2014-08-15 2 views
0

Я нацелен на 100% -ное покрытие на новое новое приложение для рельсов. У меня есть только один ресурс, сгенерированный автоматически.Как протестировать базу данных с помощью Minitest?

Для создания и обновления, сгенерированный исходный код содержит случай «else», инициированный при сбое базы данных (сбой не удалось).

# POST /projects 
# POST /projects.json 
def create 
    @project = Project.new(project_params) 

    @project.user = current_user 

    respond_to do |format| 
    if @project.save 
     format.html { redirect_to projects_url, notice: 'Project was successfully created.' } 
     format.json { render :show, status: :created, location: @project } 
    else 
     format.html { render :new } 
     format.json { render json: @project.errors, status: :unprocessable_entity } 
    end 
    end 
end 

Как Это часть моего контроллера (и может включать в себя выделенное поведение как перенаправление или сообщение об ошибке), я хочу, чтобы проверить его в единичном испытании под MiniTest.

У меня есть начало решения с созданием теста, содержащего ActiveRecord::Base.remove_connection. Я также создать функцию Teardown, содержащий обратное: ActiveRecord::Base.estabish_connection

test "should not create project" do 
    assert_equal('Project.count') do 
    ActiveRecord::Base.remove_connection 
    post :create, project: { name: @project.name, user_id: @project.user_id } 
    end 

    assert_redirected_to projects_path 
end 

и восстановить соединение для других тестов:

teardown do 
    ActiveRecord::Base.establish_connection 
end 

Это не приемлемо для (по крайней мере) две причины:

  • тест заканчивается в исключении ConnectionNotEstablished, который не является целью теста, и после этого я не могу проверить поведение самого контроллера (перенаправление)
  • establish_connection выполняется на каждом тесте (бесполезный 90% времени)

Спасибо за ваши предложения!

EDIT: добавлена ​​исходный код

+0

Вы можете включать в себя тестируемого кода и вашего тестового кода? Было бы полезно убедиться, что мы правильно понимаем, как работает ваша логика. – jstim

+1

Похоже, вы просто хотите создать макет, который замыкает процесс сохранения с определенным возвращаемым значением. (в этом случае он вернет false, чтобы поразить ваш случай). https://www.relishapp.com/rspec/rspec-mocks/v/2-6/docs/message-expectations – jstim

+0

Да, это может быть решение! Спасибо за URL, но мне не ясно, как это использовать в случае действия ActiveRecord. Можете ли вы написать примерно (непроверенный) какой-нибудь код, чтобы дать мне ногу? – gbetous

ответ

0

Как я уже говорил в моем комментарии, я думаю, что вы хотите использовать макет вместо отсоединения базы данных. Поскольку вы используете @project.save, чтобы проверить, сохранилось ли сохранение, мы хотим, чтобы он возвращал false вместо повышения ошибки ConnectionNotEstablished.

Мы можем попытаться использовать MiniTest::Mock, чтобы выполнить это, но другие люди могут использовать внешнюю насмешливую библиотеку, такую ​​как Mocha.

Примечание: Я не использую MiniTest, так что это моя догадка

test "should not create project" do 
    Project.expect(:find, @project) do 
    @project.expect(:save, false) do 
     assert_equal('Project.count') do 
     post :create, project: { name: @project.name, user_id: @project.user_id } 
     end 
    end 
    end 

    assert_redirected_to projects_path 
end 

Если вы используете мокко, это может выглядеть примерно так:

test "should not create project" do 
    Project.any_instance.stubs(:save).returns(false) 
    assert_equal('Project.count') do 
    post :create, project: { name: @project.name, user_id: @project.user_id } 
    end 

    assert_redirected_to projects_path 
end 
Смежные вопросы