The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
test/spec on Rails and assert_difference

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Patrick Lenz

Posts: 168
Nickname: scoop
Registered: Apr, 2005

Patrick Lenz is the lead developer at freshmeat.net and a contributor to the typo weblog engine
test/spec on Rails and assert_difference Posted: Apr 20, 2007 11:48 PM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Patrick Lenz.
Original Post: test/spec on Rails and assert_difference
Feed Title: poocs.net
Feed URL: http://feeds.feedburner.com/poocsnet
Feed Description: Personal weblog about free and open source software, personal development projects and random geek buzz.
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Patrick Lenz
Latest Posts From poocs.net

Advertisement

I have a certain feeling that the style of doing Behavior Driven Development (BDD) sees a little more adoption than, say, a year ago. With RSpec being the more rigorous kid on the block, test/spec by Christian Neukirchen seems to be a little less intruiging. (Yes, RSpec does have its place, too.)

What is test/spec after all?

To quote its website:

test/spec layers an RSpec-inspired interface on top of Test::Unit, so you can mix TDD and BDD (Behavior-Driven Development).

This especially convenient if you���re porting tests of an existing application over from TDD to BDD-style. test/spec blessed tests can be run alongside of Test::Unit based tests and they can even live in the same files if you dare. For a more thorough explanation of the reasoning behind BDD, see its Wikipedia entry.

test_spec_on_rails

Starting out as a simple endorsement by Rick Olson when he discovered test/spec, the test spec on rails plugin recently got a really nice make-over by Per Wigren.

This new version (which, technically, isn���t a version after all ��� we���re talking Subversion revisions here) provides all sorts of handy wrappers for more Rails-specific assertions, that previously had to be used in all their nakedness and purity before. Here���s a rundown of the new prettyness:


@user.should.validate
@user.should.not.validate

should.redirect_to :action => 'show'
status.should.be :success
template.should.be "foo/show.rhtml"

page.should.select "form#user_form"

Wrappers for assert_difference

If you���ve ever used assert_difference before (the original of which appeared as a code snippet on project.ion.ist), you���re probably unable to live without it. Not having to store before states manually to compare them to an after state in your tests is such a simple, yet effective way to DRY up your tests.


def test_new_publication
  assert_difference(Publication, :count) do
    post :create, :publication => {...}
    # ...
  end
end

But now that you���ve been drinking the test/spec kool-aid, what���s that assert_something call doing in your test? Well, what about this:


context 'Blog' do
  specify 'should create blog' do
    lambda {
      Blog.create :title => '...'
    }.should.change(Blog, :count)
  end
end

Admittedly, the lambda { } part isn���t the sexiest on the planet. But it fits nicely into the rest of the ���should��� specifications. Oh, and there���s a ���not��� part, too!

Here���s the code that makes this work (assuming you���ve installed the test_spec gem1 and the test_spec_on_rails plugin2). Just put it at the bottom of test/test_helper.rb.


# Credits: http://project.ioni.st/post/218#post-218
module Test::Unit::AssertDifference
  def assert_difference(object, method = nil, difference = 1)
    initial_value = object.send(method)
    yield
    assert_equal initial_value + difference, object.send(method), "#{object}##{method}"
  end

  def assert_no_difference(object, method, &block)
    assert_difference object, method, 0, &block
  end
end

# Extension for test/spec/rails, wraps assert_difference
module Test::Spec::Rails
  module ShouldDiffer
    def differ(*args)
      assert_difference(*args, &@object)
    end
    alias :different :differ
    alias :change :differ
  end
  module ShouldNotDiffer
    def differ(*args)
      assert_no_difference(*args, &@object)
    end
    alias :different :differ
    alias :change :differ
  end
end

Test::Spec::Should.send(:include, Test::Unit::AssertDifference)
Test::Spec::Should.send(:include, Test::Spec::Rails::ShouldDiffer)
Test::Spec::ShouldNot.send(:include, Test::Unit::AssertDifference)
Test::Spec::ShouldNot.send(:include, Test::Spec::Rails::ShouldNotDiffer)

Have fun refactoring your tests!


  1. sudo gem install test_spec
  2. script/plugin install http://svn.techno-weenie.net/projects/plugins/test_spec_on_rails/

Read: test/spec on Rails and assert_difference

Topic: Ideas for the Ruby Production Archive -- some self-critique Previous Topic   Next Topic Topic: Ruby on Rails and Apache Solr: Getting started with acts_as_solr

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use