title: When and when not to stub/mock a test
body: <p>I am making a concerted effort to wrap my head around Rspec in order to move towards more of a TDD/BDD development pattern. However, I'm a long way off and struggling with some of the fundamentals:</p>
  
  <p>Like, when exactly should I be using mocks/stubs and when shouldn't I?</p>
  
  <p>Take for example this scenario: I have a <code>Site</code> model that <code>has_many :blogs</code> and the <code>Blog</code> model <code>has_many :articles</code>. In my <code>Site</code> model I have a callback filter that creates a default set of blogs and articles for every new site. I want to test that code, so here goes:</p>
  
  <pre><code>describe Site, "when created" do
  
    include SiteSpecHelper
  
    before(:each) do
      @site = Site.create valid_site_attributes
    end
  
    it "should have 2 blogs" do
      @site.should have(2).blogs
    end
  
    it "should have 1 main blog article" do
      @site.blogs.find_by_slug("main").should have(1).articles
    end
  
    it "should have 2 secondary blog articles" do
      @site.blogs.find_by_slug("secondary").should have(2).articles
    end
  
  end
  </code></pre>
  
  <p>Now, if I run that test, everything passes. However, it's also pretty slow as it's creating a new Site, two new Blogs and three new Articles - for every single test! So I wonder, is this a good candidate for using stubs? Let's give it a go:</p>
  
  <pre><code>describe Site, "when created" do
  
    include SiteSpecHelper
  
    before(:each) do
      site = Site.new
      @blog = Blog.new
      @article = Article.new
      Site.stub!(:create).and_return(site)
      Blog.stub!(:create).and_return(@blog)
      Article.stub!(:create).and_return(@article)
      @site = Site.create valid_site_attributes
    end
  
    it "should have 2 blogs" do
      @site.stub!(:blogs).and_return([@blog, @blog])
      @site.should have(2).blogs
    end
  
    it "should have 1 main blog article" do
      @blog.stub!(:articles).and_return([@article])
      @site.stub_chain(:blogs, :find_by_slug).with("main").and_return(@blog)
      @site.blogs.find_by_slug("main").should have(1).articles
    end
  
    it "should have 2 secondary blog articles" do
      @blog.stub!(:articles).and_return([@article, @article])
      @site.stub_chain(:blogs, :find_by_slug).with("secondary").and_return(@blog)
      @site.blogs.find_by_slug("secondary").should have(2).articles
    end
  
  end
  </code></pre>
  
  <p>Now all the tests still pass, and things are a bit speedier too. But, I've doubled the length of my tests and the whole exercise just strikes me as utterly pointless, because I'm no longer testing my code, I'm just testing my tests.</p>
  
  <p>Now, either I've completely missed the point of mocks/stubs, or I'm approaching it fundamentally wrong, but I'm hoping someone might be able to either:</p>
  
  <ul>
  <li>Improve me tests above so it uses stubs or mocks in a way that actually tests my code, rather than my tests.</li>
  <li>Or, tell me if I should even be using stubs here - or whether in fact this is completely unnecessary and I should be writing these models to the test database.</li>
  </ul>