...

/

Using Mocks to Simulate Database Failure

Using Mocks to Simulate Database Failure

Learn how to simulate database failure using mocks.

Simulating database failure

A common use case for test doubles in Rails is to simulate database failures. Let’s look at how we can do that.

In the past, we would have suggested testing for failure at the controller level. However, Rails has basically deprecated controller tests for reasons we’ll talk about in Testing Rails Display Elements, and so we’d like to stay within the bounds of Rails community behavior.

Let’s look at the project-creation functionality we wrote at the beginning of the book. We wrote a controller:

Press + to interact
def create
@workflow = CreatesProject.new(
name: params[:project][:name],
task_string: params[:project][:tasks])
@workflow.create
if @workflow.success?
redirect_to projects_path
else
@project = @workflow.project
render :new
end
end

Workflow

The controller largely defers to a workflow object that does the actual work:

Press + to interact
class CreatesProject
attr_accessor :name, :project, :task_string
def initialize(name: "", task_string: "")
@name = name
@task_string = task_string || ""
@success = false
end
def success?
@success
end
def build
self.project = Project.new(name: name)
project.tasks = convert_string_to_tasks
project
end
def create
build
result = project.save
@success = result
end
def convert_string_to_tasks
task_string.split("\n").map do |one_task|
title, size_string = one_task.split(":")
Task.new(title: title, size: size_as_integer(size_string))
end
end
def size_as_integer(size_string)
return 1 if size_string.blank?
[size_string.to_i, 1].max
end
end

Now we have two different pieces of point-of-failure logic to deal with:

  • In the event of a database failure, the ...