Isolated controller and view testing in merb 2

Posted by Tim Connor Mon, 17 Dec 2007 08:41:00 GMT

As part of learning rspec for blerb, I’m working on better mocking for truer isolation tests. This includes true unit tests for models, controllers, and views, unlike the rails/testunit standard approach. This involves, primarily, mocking out the models and turning rendering off for the controller testing, and figuring out how to test just the rendering without the rest of the stack, for the views. I won’t claim any of this is well organized, or finalized, as we are just figuring out how to do some of it in the first place, but feel free to crib any of this you like off the git-web for blerb.

First a controller


describe “Articles Controller”, “index action” do
before(:each) do
article1 = mock("article") @article2 = mock("article") @articles = [article1, article2] Article.should_receive(:all).and_return(articles)
@controller = Articles.build(fake_request)
@controller.stub!(:render)
@controller.dispatch(‘index’)
end

it “should get successfully” do @controller.status.should == 200 end it “should assign all articles” do controller.instance_variable_get("articles").should == @articles end

end

The one non-intuitive part (for me), was making sure to stub render – otherwise you’ll be calling the view, and getting errors on your mocks because the view is calling methods you didn’t mock/stub out. Thus, it is key to isolate the controller from the model and the view if you want to easily test it, in this style. Oh yeah, and knowing about fake_request as part of the merb testing help.

The slightly trickier part was doing the same for the views. I dug through the merb source, and got most of the way, but hadn’t figured out how to pass in assigned instance variables by creating a dummy ViewContext, when ezra gave me a hand. I would NOT (and will not long term) do it exactly like this, but rather extract some sort of spec_helper to wrap the fake view_context creation and template engine calls, but it’s useful as is for an illustrative example.

class FakeArticleController
  def initialize(articles)
    @articles = articles
  end
end

describe "/articles" do
  before(:each) do
    @article1 = mock("article")
    @article2 = mock("article")
    @article1.should_receive(:title).and_return("Article 1")
    @article2.should_receive(:title).and_return("Article 2")    
    Article.stub!(:all).and_return([@article1,@article2])

    @template = "#{MERB_VIEW_ROOT}/articles/index.html.erb"
    @engine = Merb::Template.engine_for(@template)
    @fake = Merb::ViewContext.new FakeArticleController.new(Article.all)
    @body = @engine.transform(:file => @template, :view_context => @fake)
  end
  
  it "should list all articles" do
    @body.should include("<li>Article 1</li>")
    @body.should include("<li>Article 2</li>")
  end
end

http access to blerb via gitweb and general update.

Posted by Tim Connor Tue, 11 Dec 2007 07:42:00 GMT

hornbeck’s master repo is available at git://42squared.com/git/blerb. Stop by #blerb if you want to hack on it. With the help of mattly and court3nay I’ve put a copy of the repo up at git.caboo.se so now there is web access to blerb source via gitweb, for those who don’t want to brave git, yet, or who already have access to git.caboo.se (I believe it’s wide open for read-only, of course), or just those that like browsing the history/changelogs/ through a webterface. I’ll be pushing up to there every so often.

On another note, we plan on borrowing everything that makes sense to from Ezra’s earlier stab at a similar project: MrBlog

Merb blog begun: blerb 6

Posted by Tim Connor Sun, 02 Dec 2007 10:44:00 GMT

It’s nowhere near being ready yet, but I made my first contributions tonight. I was going to code up one myself, but a couple other caboosers already where planning on it, and since I am somewhat time constrained on personal projects, that was perfect.

Just getting started was quite a bit to bite off, though, as it involved learning git, datamapper, merb, rspec, and how the last three all play together (like how to use rspecs built-in mocking when trying to do controller specs in merb). I got it checked out and my first minor changes specc’ed and made, and pushed back upstream, though, so it should go easier from here out.

I will post more when there is something more to say (like maybe a repo to browse, or a website, or something that is usable as a blog)

Update: The other contributor to blerb so far is John Hornbeck.