On Aug 23, 2011, at 5:02 AM, foreverman wrote:
The above controller test will pass even the ‘show’ template doesn’t
exist.
I am curious if this is a bug or I did something wrong.
Neither. There’s a bit of history here so bear with me.
The names used in Rails for the different kinds of tests it offers do
not align with the names we used to use before Rails came along. Here
are some older definitions (which are the ones to which I subscribe, but
that doesn’t mean “they are the right ones”):
Unit test: specifies behavior of an object in isolation.
Integration test: specifies behavior of two or more objects in which
there are at least two bits of non-trivial behavior.
Functional test: specifies how the application behaves (from a user
perspective, or close facsimile)
System test: specifies how a system of applications behave
These each cover progressively wider scope: unit, integration,
functional, system.
Based on that nomenclature, what Rails calls unit, functional, and
integration tests are really integration (model + db), integration (mvc
- db), and functional tests (mvc + db + routing/sessions).
The rspec-rails gem aims to support the more traditional scopes by
offering unit tests for controllers and views. This is what you’ve come
up against: a controller spec is intended to be a unit test for the
controller. To support this, rspec-rails (1.x) does not actually render
any views at all. If the spec says the controller should render
“foo/bar”, and the controller renders “foo/bar”, then the example passes
whether or not the view exists. In a BDD process, we work from the
outside-in, so before the controller spec exists, there would be a
failing “integration spec” (which were called that to align with Rails’
nomenclature in rspec-rails-1, but are called “request specs” in
rspec-rails-2 - perhaps we should really call these “functional specs”,
but that might just make things more confusing). That serves two
purposes: it describes the behavior from a user perspective (when I
submit this form with valid data, then xyz happens), and it also
provides test coverage that prove
s that the isolated parts specified in model, view, controller, and
helper specs all play nice together.
If you prefer to treat controller specs as Rails functional tests (which
are mvc + db integration specs, but not functional tests since they
bypass the router (sort of) and sessions (sort of)), you can tell
rspec-rails-1 to render views with the “integrate_views” declaration
(“render_views” in rspec-rails-2):
globally
Spec::configure do |c|
c.integrate_views
end
or
for one spec
describe ThingsController do
integrate_views
…
end
HTH,
David