Making Test Fixtures
Learn to add test fixtures to run the actual tests.
We'll cover the following...
At this point, we can dig deeper and exercise individual validations. Let’s look at three of the many possible tests.
First, we’ll check that the validation of the price works the way we expect:
test "product price must be positive" doproduct = Product.new(title: "My Book Title",description: "yyy",image_url: "zzz.jpg")product.price = -1assert product.invalid?assert_equal ["must be greater than or equal to 0.01"],product.errors[:price]product.price = 0assert product.invalid?assert_equal ["must be greater than or equal to 0.01"],product.errors[:price]product.price = 1assert product.valid?end
In this code, we create a new product and try setting its price to -1
, 0
, and +1
, in lines 10, 15, and 20 respectively, validating the product each time. If our model is working, the first two should be invalid, and we verify that the error message associated with the price
attribute is what we expect.
The last price is acceptable, so we assert that the model is now valid. Some folks would put these three tests into three separate test methods, which is perfectly reasonable.
Next, we test that we’re validating that the image URL ends with one of the .gif
, .jpg
, or .png
:
def new_product(image_url)Product.new(title: "My Book Title",description: "yyy",price: 1,image_url: image_url)endtest "image url" dook = %w{ fred.gif fred.jpg fred.png FRED.JPG FRED.Jpghttp://a.b.c/x/y/z/fred.gif }bad = %w{ fred.doc fred.gif/more fred.gif.more }ok.each do |image_url|assert new_product(image_url).valid?,"#{image_url} shouldn't be invalid"endbad.each do |image_url|assert new_product(image_url).invalid?,"#{image_url} shouldn't be valid"endend
We’ve mixed things up a bit here. Rather than write the nine separate tests, we’ve used a couple of loops. One loop checks the cases we expect to pass validation and the second loop tries cases we expect to fail. At the same time, we factored out the common code between the two loops.
We also added an extra parameter to our assert method calls. All of the testing assertions accept an optional trailing parameter containing a string. This will be written along with the error message if the assertion fails and can be useful for diagnosing what went wrong.
Finally, our model contains a validation that checks that all the product titles in the database are unique. To test this, we need to store product data in the database.
One way to do this would be to have a test create a product, save it, then create ...