Hi, > def do_verb(params = @params) > post :create, :album => params > end > > it "should change the Albums count by 1 after POST" do > lambda do > @album.should_receive(:save).and_return(true) > do_verb > end.should change(Album, :count).by(1) > end
You expect the database count to change, but because you mock away the method :save, the object won't get saved. You don't need to test for Album#count to increase; if the 'save' method is called for the object, you can rest assured there's one more object in the db. And if save doesn't work as it should, the problem isn't in your code but in the ActiveRecord instead. I'm not sure, but I guess that people who make this kind of mistake think that mocking/stubbing a method doesn't prevent the calling of the original method, but it does. The whole idea in mocking is to specify _expectations related to behaviour_. The following (simplified) rule could be stated as follows: if you use mocks, you don't need to (nor should) use state-based assertions, as lambda {...}.should change(Model, :method) does. And vice versa; if you use state to test stuff, you don't use mocks. But as I said, it is an oversimplification. For example, usually you don't want to mock or stub methods to unit/thingy under the test, but you _should_ probably mock/stub methods related to associated classes. That said, some people consider use of mocks dangerous and brittle to changes. I don't - if you have a language terse enough (like Ruby) and an advanced speccing framework (like RSpec), changing your tests to reflect intended changes to code is not a chore too tedious for me. Besides, to ensure at least mediocre test/spec coverage you should automate your integration tests as well, where you don't use mock/stub objects at all (with the exception of very expensive/non-deterministic resources such as say, network and random number generators). As for the other question, I learned BDD by reading the well-documented RSpec site itself and random blog entries related to BDD and Rails. But to really learn BDD well, I'd recommend any newcomer to get acquaintanted with core concepts of BDD first, like unit testing and mocks/stubs. For the former I recommend books related to Test-Driven Development like those by David Astel and Kent Beck, and for the latter articles related to mocking: Fowler's Mocks Aren't Stubs (http://martinfowler.com/articles/mocksArentStubs.html) is an excellent explanation (or a viewpoint; some people don't make such difference between the two) for both mocks and stubs, and the article "Mock Roles, not Objects" (http://www.jmock.org/oopsla2004.pdf) is an invaluable gem in itself -- for me it took two reads to really understand (I hope!) it, though, with more than one year in between (the catch is that the paper appears to be simple; it doesn't contain cryptic formulas or ingenious mathematical proofs, however, I believe it may take a while before the reader really, really understands the subject of the article). -- "One day, when he was naughty, Mr Bunnsy looked over the hedge into Farmer Fred's field and it was full of fresh green lettuces. Mr Bunnsy, however, was not full of lettuces. This did not seem fair." -- Terry Pratchett, Mr. Bunnsy Has An Adventure _______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users