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
|
Feature: Customizing the overwritten class
Typically, when you specify a contract to be verified, you do it like this:
describe SomeClass do
verify_contract(:some_fake_name)
end
When you do this, under the hood Bogus replaces `SomeClass` with a proxy that records any calls made to the class and its instances for the duration of the test.
If the class you want to be overwritten is not the one that is described, you can customize it like so:
describe "not a class" do
verify_contract(:some_fake_name) { SomeClass }
end
In case there is no described class and you don't provide a custom one to be overwritten, the class will be guessed based on the name of the fake:
describe "not a class" do
verify_contract(:some_fake_name)
end
In the above example, Bogus will try to overwrite a class named `SomeFakeName`.
Background:
Given a file named "library.rb" with:
"""ruby
class PublicLibrary
def initialize
@books = []
end
def has_book?(book)
@books.include?(book)
end
def checkout(book)
@books.delete(book)
end
def return(book)
@books << book
end
end
"""
Given a file named "student.rb" with:
"""ruby
class Student
def read(book, library = PublicLibrary.new)
if library.has_book?(book)
library.checkout(book)
end
end
end
"""
And a spec file named "student_spec.rb" with:
"""ruby
require_relative 'student'
require_relative 'library'
describe Student do
fake(:library) { PublicLibrary }
it "checks out the book from library if it is available" do
student = Student.new
mock(library).has_book?("Moby Dick") { true }
mock(library).checkout("Moby Dick") { "Moby Dick" }
student.read("Moby Dick", library)
end
it "does not check out the book from library if not available" do
student = Student.new
mock(library).has_book?("Moby Dick") { false }
student.read("Moby Dick", library)
expect(library).not_to have_received.checkout("Moby Dick")
end
end
"""
Scenario: Verifying contract for a class that is not the described_class
Then spec file with following content should pass:
"""ruby
require_relative 'library'
describe "Borrowing books from library" do
verify_contract(:library) { PublicLibrary }
let(:library) { PublicLibrary.new }
it "allows checking out books that are in the inventory" do
library.return("Moby Dick")
expect(library.has_book?("Moby Dick")).to be_true
end
it "does not allow checking out unavailable books" do
expect(library.has_book?("Moby Dick")).to be_false
end
it "marks books as unavailable after they are checked out" do
library.return("Moby Dick")
library.checkout("Moby Dick")
expect(library.has_book?("Moby Dick")).to be_false
end
end
"""
|