如何使用Minitest测试数据库故障?

时间:2014-08-15 21:13:30

标签: ruby-on-rails ruby unit-testing activerecord

我的目标是在全新的铁轨应用上实现100%的覆盖率。我只有一个资源,自动生成。

对于创建和更新操作,生成的源代码包含“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的测试。我还创建了一个包含相反的拆解功能: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%的时间没用)

感谢您的建议!

编辑:添加了代码来源

1 个答案:

答案 0 :(得分: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

如果你使用mocha,它可能看起来像这样:

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