Is it possible (and reasonable) to write Controller tests and classes before writing the underlying Model classes? I thought I saw notes on how to do that, but now I can’t find the recipe.
For example, consider the following controller:
# file: app/controllers/premises_controller.rb
class PremisesController < ApplicationController
def create
@premise = Premise.new(params[:premise])
respond_with @premise
end
end
Can I test this controller code before creating the underlying Premise model and premises? I know the following won’t work — how would you re-write it (if it’s possible)?
# file: spec/controller/premise_spec.rb
require "spec_helper.rb"
describe PremisesController do
context 'POST create' do
it 'should assign a new Premise to @premise' do
premise = stub_model(Premise)
Premise.stub(:create) { premise }
post :create
assigns(:premise).should == premise
end
end
end
end
update
The more I think about it, the more I’m convinced that I do need to define the Premise class — the PremisesController code needs to reference it. So I’ll change my question to “is it necessary to create the underlying premises database table in order to run the PremisesController tests?”
At this point, I don’t see a good way around it (without changing the PremisesController code, which defeats the point of testing). For example, the call to respond_with calls @premise.has_errors? which in turn accesses the database to fetch the column names. Unless I’m willing to stub methods internal to ActiveRecord, I don’t see how to avoid a hit to the DB.
But I’d love to be shown otherwise.
Okay – I’ve made my peace with this: it’s not practical to create any meaningful tests unless the database table exists — too many bits of ActiveRecord depend on having the table defined.
But this doesn’t prevent writing test that with a clean separation between the controller and the model. This is eloquently covered by dchelimsky Himself in this RSpec issue. The gist of his post:
getand verifies the generated json response.By the way, I really recommend reading David’s post — he takes you through a step-by-step process, explaining the philosophy and the reasoning behind each step.