At the end of Chapter 8 of Agile Web Development With Rails, there is a seemingly innocuous exercise that says:
Write some functional tests for the product maintenance application ...
Sounds easy enough :) And I like writing tests. Yes, I'm weird that way.
The existing tests are all happy-path.
require 'test_helper'
class ProductsControllerTest < ActionController::TestCase
setup do
@product = products(:one)
@update = {
title: 'Lorem Ipsum',
description: 'Wibbles are fun!',
image_url: 'lorem.jpg',
price: 19.95
}
end
test "should create product" do
assert_difference('Product.count') do
post :create, product: @update
end
assert_redirected_to product_path(assigns(:product))
end
end
And so I decided to try adding a test for when you can't create a product
@invalid_product = {
price: 0.00,
title: 'abc'
}
test "should not create product" do
post :create, product: @invalid_product
assert_template :new
end
And all was well. Or, almost. There were no tests for the JSON path in the controller:
# POST /products
# POST /products.json
def create
@product = Product.new(params[:product])
respond_to do |format|
if @product.save
format.html { redirect_to @product, notice: 'Product was successfully created.' }
format.json { render json: @product, status: :created, location: @product }
else
format.html { render action: "new" }
format.json { render json: @product.errors, status: :unprocessable_entity }
end
end
end
Thinking this would be easy enough to do, I ended up reading an untold number of Stack Overflow posts on the subject; it seems like it's changed between different versions of Rails. Finally, after about an hour, I ended up with something that worked. It seems perfectly simple and obvious in hindsight, but in case anyone else's mind works like mine, here it is :)
test "should not create product (JSON)" do
post :create, :data => @invalid_product.to_json, :format => "json"
assert_response :unprocessable_entity
end
Note: This is what currently works on Rails 3.2.8 and Ruby 1.9.3p194.
Comments