Demo 8: Rails Model Validations and Testing
▶️ Play from the beginning (~30 minutes)
In this demonstration, I will expand on the previous demo on the Rails MVC model by explaining how to add input validations to model classes and how to create automated tests of model classes.
Before we dive in with common tasks regarding input validations and testing, let’s consider how these things fit into the Rails architecture.
- ▶️ Add input validations to one or more of the model attributes (see
validates
).
- ▶️ Launch the Rails Console (see
rails c
).
- ▶️ Attempt to create a model object with an invalid attribute using the class method
create
. This command should fail.
- ▶️ Inspect the database to confirm that the record was not created (see the Firefox SQLite Manager Add-on).
- ▶️ Inspect details about the errors using the methods
errors.any?
, errors.count
, and errors.full_messages
.
- ▶️ For purposes of comparison, attempt to create a model object with an invalid attribute using the class method
create!
. Note that this time an exception is thrown.
- ▶️ Check in changes: Stage, commit, and push the new input validations to the Git repo (see
git add -A
, git commit ...
, and git push
).
▶️ Check-in Changes: changeset, snapshot
▶️ 2. Adding and Running Unit Tests
▶️ 2.1. Adding Test Fixtures
- ▶️ Add some test data to the appropriate YAML file in the folder
test/fixtures/
. Make these objects such that they are representative of a typical record and are valid (i.e., will not violate an input validation).
- ▶️ Check in changes: Stage, commit, and push the new test fixtures to the Git repo (see
git add -A
, git commit ...
, and git push
).
▶️ Check-in Changes: changeset, snapshot
▶️ 2.2. Adding a Test for a Typical, Valid Model Object
- ▶️ Open in a code editor the appropriate unit test file in the folder
test/models/
.
- ▶️ Create a new empty test case that will test that a valid record can be saved without error.
- ▶️ First, make the test case retrieve a fixture object.
- ▶️ Next, make the test case check that the object is valid (see the
assert
and valid?
methods).
- ▶️ Test and debug: Run all tests created so far (see
rails test
). All tests should pass.
- ▶️ Check in changes: Stage, commit, and push the new test case to the Git repo (see
git add -A
, git commit ...
, and git push
).
▶️ Check-in Changes: changeset, snapshot
▶️ 2.3. Adding a Test for an Invalid Model Object
- ▶️ Create a new empty test case that will test one of the input validations.
- ▶️ First, make the test case retrieve a fixture object.
- ▶️ Next, make the test case set an attribute to an invalid value (see the model setter methods).
- ▶️ Finally, make the test case check that the object is invalid (see the
assert_not
and valid?
methods).
- ▶️ Test and debug: Run all tests created so far (see
rails test
). All tests should pass.
- ▶️ Check in changes: Stage, commit, and push the new test case to the Git repo (see
git add -A
, git commit ...
, and git push
).
▶️ Check-in Changes: changeset, snapshot
▶️ 3. Catching Bugs with the Automated Tests
This part is intended to illustrate how the test cases we created can be useful for helping us catch bugs that we might accidentally introduce into our code.
▶️ 3.1. Catching a Syntax Error
- ▶️ Introduce a syntax error in the model class.
- ▶️ Run all tests created so far (see
rails test
). One or more of the tests should fail, effectively alerting us to the syntax error.
- ▶️ Undo the erroneous change to the working tree (see
git checkout -- ...
).
▶️ 3.2. Catching a Logic Error
- ▶️ Introduce a logic error in an input validation of the model class, such that the test data would not be handled correctly by it.
- ▶️ Run all tests created so far (see
rails test
). This time, one or more of the tests should fail, effectively alerting us to the logic error.
- ▶️ Undo the erroneous change to the working tree (see
git checkout -- ...
).