1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
Feature: Replacing classes with fakes
Bogus is an opinionated piece of software. One of the opinions we have is that you should use dependency injection to make your code more modular and your classes easier to compose. However, we respect the fact, that this is currently not very popular among Ruby developers.
In order to make life easier for people who choose not to use Dependency Injection, Bogus makes it convenient to replace chosen classes in your tests with fakes.
All you need to do, is put the following code in your describe:
fake_class(FooBar, foo: "bar")
Which is a shortcut for:
before do
fake_class(FooBar, foo: "bar")
end
Background:
Given a file named "app.rb" with:
"""ruby
require "yaml"
class Library
FILE = "library.yml"
def self.books
YAML.load_file(FILE)
end
end
class BookIndex
def self.by_author(author)
Library.books.select{|book| book[:author] == author}
end
end
"""
And a file named "spec_helper.rb" with:
"""ruby
require 'bogus/rspec'
require_relative 'app'
"""
Scenario: Replacing classes and contracts
Given a file named "library_spec.rb" with:
"""ruby
require_relative 'spec_helper'
require 'fileutils'
describe Library do
verify_contract(:library)
it "reads the books from the yaml file" do
books = [{name: "Tom Sawyer", author: "Mark Twain"},
{name: "Moby Dick", author: "Herman Melville"}]
File.open(Library::FILE, "w") { |f| f.print books.to_yaml }
expect(Library.books).to eq(books)
end
after do
FileUtils.rm_rf(Library::FILE)
end
end
"""
And a file named "book_index_spec.rb" with:
"""ruby
require_relative 'spec_helper'
describe BookIndex do
verify_contract(:book_index)
it "returns books written by author" do
tom_sawyer = {name: "Tom Sawyer", author: "Mark Twain"}
moby_dick = {name: "Moby Dick", author: "Herman Melville"}
fake_class(Library, books: [tom_sawyer, moby_dick])
expect(BookIndex.by_author("Mark Twain")).to eq([tom_sawyer])
end
end
"""
When I run `rspec book_index_spec.rb library_spec.rb`
Then the specs should pass
Scenario: Replacing classes and contracts with a different fake name
Given a file named "library_spec.rb" with:
"""ruby
require_relative 'spec_helper'
require 'fileutils'
describe Library do
verify_contract(:book_repository)
it "reads the books from the yaml file" do
books = [{name: "Tom Sawyer", author: "Mark Twain"},
{name: "Moby Dick", author: "Herman Melville"}]
File.open(Library::FILE, "w") { |f| f.print books.to_yaml }
expect(Library.books).to eq(books)
end
after do
FileUtils.rm_rf(Library::FILE)
end
end
"""
And a file named "book_index_spec.rb" with:
"""ruby
require_relative 'spec_helper'
describe BookIndex do
verify_contract(:book_index)
it "returns books written by author" do
tom_sawyer = {name: "Tom Sawyer", author: "Mark Twain"}
moby_dick = {name: "Moby Dick", author: "Herman Melville"}
fake_class(Library, fake_name: :book_repository,
books: [tom_sawyer, moby_dick])
expect(BookIndex.by_author("Mark Twain")).to eq([tom_sawyer])
end
end
"""
When I run `rspec book_index_spec.rb library_spec.rb`
Then the specs should pass
Scenario: Replacing classes with a macro
Given a file named "book_index_spec.rb" with:
"""ruby
require_relative 'spec_helper'
describe BookIndex do
fake_class(Library, books: [])
it "returns books written by author" do
expect(BookIndex.by_author("Mark Twain")).to eq([])
end
end
"""
When I run `rspec book_index_spec.rb`
Then the specs should pass
|