...

/

Testing for Failure

Testing for Failure

Learn how to do failure-path testing in unit tests.

Failure-path testing

Failure is always a possibility, so we need to test for it. We prefer to do failure-path testing in unit tests rather than end-to-end tests. Success requires the entire system to work in concert. A failure response can usually be isolated to one component. That said, it’s often useful to have one end-to-end failure test, especially in cases where the failure is easily usable and visible to a typical user.

We haven’t yet learned about the tools that will allow us to fake failure. That requires a mock object package (see Using Test Doubles as Mocks and Stubs). But in this case, it’s not hard to create a real failure by adding a validation that we can then not fulfill.

Let’s first see what an end-to-end failure test might look like by illustrating what would happen if we allow a user to create a project without a name:

class CreatesProject
    attr_accessor :name, :project, :task_string

    def initialize(name: "", task_string: "")
        @name = name
        @task_string = task_string
    end

    def build
        self.project = Project.new(name: name)
        project.tasks = convert_string_to_tasks
        project
    end

    def create
        build
        project.save
    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
Adding code to add_project_spec.rb file

This test is similar to the original feature test, except that the name field is “filled in” with an empty string. We could not include that line, but it’s better to explicitly show ...