为了向更多TDD/BDD开发模式迈进,我正在齐心协力围绕Rspec进行研究。然而,我还有很长一段路要走,并且在一些基本面上挣扎:何时以及何时不存根/模拟测试
就像我应该在什么时候使用模拟/存根,什么时候不应该?举例来说,这种情况下:我有一个Site
模型has_many :blogs
和Blog
模型has_many :articles
。在我的Site
模型中,我有一个回调过滤器,为每个新网站创建一组默认的博客和文章。我想测试该代码,所以这里有:
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
现在,如果我运行该测试,一切都会通过。然而,它也很慢,因为它会创建一个新网站,两个新博客和三个新文章 - 每一个测试!所以我想知道,这是使用存根的好候选者吗?让我们一起去吧:
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
现在所有的测试仍然通过,事情也有点快。但是,我的测试时间增加了一倍,整个练习让我觉得完全毫无意义,因为我不再测试我的代码,我只是测试我的测试。现在
,或者我已经完全错过了嘲笑/存根的点,或者我接近它根本上就是错误的,但我希望有人也许能够之一:
- 提高我上面的测试所以它以实际测试我的代码的方式使用存根或模拟,而不是我的测试。
- 或者,告诉我是否应该在这里使用存根 - 或者实际上这是完全不必要的,我应该将这些模型写入测试数据库。
谢谢,这是一个有用的回应。:) – aaronrussell 2010-09-14 12:41:36