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.
# gem install moonmaster9000-dupe
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.author do |author_name| Dupe.find(:author) {|a| a.name == author_name} end end
and the following cucumber step definitions (utilizing Dupe.create):
Given /^an author "([^\"]*)"$/ do |author| Dupe.create :author, :name => author end Given /^a book "([^\"]*)" by "([^\"]*)"$/ do |book, author| Dupe.create :book, :title => book, :author => 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>).
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/