Dupe
There are lots of great tools out there to ease the burden of prototyping ActiveRecord objects while cuking your application (e.g., thoughtbot’s “Factory Girl”). But what about prototyping ActiveResource records? That’s where Dupe steps in.
Installation
First, install the gem:
# gem install moonmaster9000-dupe
Then add this to your cucumber.rb environment (config/environments/cucumber.rb)
config.gem 'moonmaster9000-dupe', :lib => 'dupe'
You might also want to add a particular version number if you want to make sure a particular feature is there:
config.gem 'moonmaster9000-dupe', :lib => 'dupe', :version => '>=0.3.0'
Example
Let’s suppose your cuking a book search application for a library that consumes a RESTFUL book datastore service via ActiveResource. You might start by writing the following feature in RAILS_ROOT/features/library/find_book.feature:
Feature: find a book
As a reader
I want to search for books
so that I can check them out and read them.
Scenario: search by author
Given an author "Arthur C. Clarke"
And a book "2001: A Space Odyssey" by "Arthur C. Clarke"
When I search for "Arthur C. Clarke"
I should see "2001: A Space Odyssey"
To get this to pass, you might first create ActiveResource models for Books and Authors that connect to the Library service:
class Book < ActiveResource::Base
self.site = 'http://bookservice.domain'
end
class Author < ActiveResource::Base
self.site = 'http://bookservice.domain'
end
Then you might create the following resource definition via Dupe.define (put it in a file with a .rb extension and place it in RAILS_ROOT/features/support/):
Dupe.define :book do |book|
book. do ||
Dupe.find(:author) {|a| a.name == }
end
end
and the following cucumber step definitions (utilizing Dupe.create):
Given /^an author "([^\"]*)"$/ do ||
Dupe.create :author, :name =>
end
Given /^a book "([^\"]*)" by "([^\"]*)"$/ do |book, |
Dupe.create :book, :title => book, :author =>
end
Dupe.create will in turn mock two service responses for each resource. For example, for the Book resource, it will mock:
# Book.find(:all) --> GET /books.xml
<?xml version="1.0" encoding="UTF-8"?>
<books type="array">
<book>
<id type="integer">1</id>
<title>2001: A Space Odyssey</title>
<author>
<id type="integer">1</id>
<name>Arthur C. Clarke</name>
</author>
</book>
</books>
# Book.find(1) --> GET /books/1.xml
<?xml version="1.0" encoding="UTF-8"?>
<book>
<id type="integer">1</id>
<title>2001: A Space Odyssey</title>
<author>
<id type="integer">1</id>
<name>Arthur C. Clarke</name>
</author>
</book>
From here, you could start scaffolding your controllers, with the assumption that Dupe will mock the responses to Book.find(<id or :all>) and Author.find(<id or :all>).
More
Dupe supports attribute defaults, attribute transformations, stubbing, resource associations, custom resource mocks, and more. Want to learn more? Consult the API documentation at moonmaster9000.github.com/dupe/api/