Shoulda, nested contexts, and should_change_by
I love some of shoulda’s macros, partially because it forces me to think about my tests and put them in setup blocks, which ends up making things cleaner.
So I ran into a case where I do an action and use should_change to make sure that a certain number of rows were added to a table, then I do it again and make sure they don’t change. So I used a nested set of contexts to handle this:
context "do it once" do
setup do
post :method, :foo => {...}
end
should_change("something", :by => 6) {Something.count}
#... other tests ...
context "do it a second time" do
setup do
post :method, :foo => {...}
end
# should it change by 6 or 0?
end
end
I wasn’t sure if the should_change applied to both the setup blocks or only the second. Turns out it’s only the second, so it should not change in the second test. Here’s proof:
require 'test_helper'
class SomethingControllerTest < ActionController::TestCase
context "outer" do
setup do
@user = Factory.create(:valid_user)
end
should_change("number of users", :by => 1) { User.count }
context "inner" do
setup do
end
should_change("number of users", :by => 0) { User.count }
end
end
end
Since I didn’t write my tests before I wrote the code I wasn’t sure if my code was bad or my test was. Now I know how the test could be structured and I could test properly.
