david chelimsky articulated man, incassets.en.oreilly.com/1/event/24/don't mock... · agenda...
TRANSCRIPT
![Page 1: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/1.jpg)
Don’t MockYourself Out
David ChelimskyArticulated Man, Inc
![Page 2: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/2.jpg)
![Page 3: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/3.jpg)
http://martinfowler.com/articles/mocksArentStubs.html
![Page 4: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/4.jpg)
Classical and Mockist Testing
![Page 5: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/5.jpg)
Classical and Mockist Testing
![Page 6: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/6.jpg)
Classical and Mockist Testing
![Page 7: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/7.jpg)
classicist mockist
![Page 8: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/8.jpg)
merbist railsist
![Page 9: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/9.jpg)
rspecist testunitist
![Page 10: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/10.jpg)
![Page 11: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/11.jpg)
ist bin einred herring
![Page 12: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/12.jpg)
The big issue here is when to use a
mock
http://martinfowler.com/articles/mocksArentStubs.html
![Page 13: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/13.jpg)
agenda๏ overview of stubs and mocks
๏ mocks/stubs applied to rails
๏ guidelines and pitfalls
๏ questions
![Page 14: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/14.jpg)
test double
![Page 15: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/15.jpg)
test stubdescribe Statement do it "uses the customer name in the header" do customer = stub("customer") customer.stub(:name).and_return('Joe Customer') statement = Statement.new(customer)
statement.header.should == "Statement for Joe Customer" endend
![Page 16: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/16.jpg)
test stubdescribe Statement do it "uses the customer name in the header" do customer = stub("customer") customer.stub(:name).and_return('Joe Customer') statement = Statement.new(customer)
statement.header.should == "Statement for Joe Customer" endend
![Page 17: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/17.jpg)
test stubdescribe Statement do it "uses the customer name in the header" do customer = stub("customer") customer.stub(:name).and_return('Joe Customer') statement = Statement.new(customer)
statement.header.should == "Statement for Joe Customer" endend
![Page 18: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/18.jpg)
test stubdescribe Statement do it "uses the customer name in the header" do customer = stub("customer") customer.stub(:name).and_return('Joe Customer') statement = Statement.new(customer)
statement.header.should == "Statement for Joe Customer" endend
![Page 19: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/19.jpg)
mock objectdescribe Statement do it "logs a message when printed" do customer = stub("customer") customer.stub(:name).and_return('Joe Customer') logger = mock("logger") statement = Statement.new(customer, logger)
logger.should_receive(:log).with(/Joe Customer/) statement.print endend
![Page 20: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/20.jpg)
mock objectdescribe Statement do it "logs a message when printed" do customer = stub("customer") customer.stub(:name).and_return('Joe Customer') logger = mock("logger") statement = Statement.new(customer, logger)
logger.should_receive(:log).with(/Joe Customer/) statement.print endend
![Page 21: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/21.jpg)
mock objectdescribe Statement do it "logs a message when printed" do customer = stub("customer") customer.stub(:name).and_return('Joe Customer') logger = mock("logger") statement = Statement.new(customer, logger)
logger.should_receive(:log).with(/Joe Customer/) statement.print endend
![Page 22: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/22.jpg)
mock objectdescribe Statement do it "logs a message when printed" do customer = stub("customer") customer.stub(:name).and_return('Joe Customer') logger = mock("logger") statement = Statement.new(customer, logger)
logger.should_receive(:log).with(/Joe Customer/) statement.print endend
![Page 23: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/23.jpg)
mock objectdescribe Statement do it "logs a message when printed" do customer = stub("customer") customer.stub(:name).and_return('Joe Customer') logger = mock("logger") statement = Statement.new(customer, logger)
logger.should_receive(:log).with(/Joe Customer/) statement.print endend
![Page 24: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/24.jpg)
method level concepts
![Page 25: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/25.jpg)
describe Statement do it "logs a message when printed" do customer = Object.new logger = Object.new customer.stub(:name).and_return('Joe Customer') statement = Statement.new(customer, logger)
logger.should_receive(:log).with(/Joe Customer/) statement.print endend
![Page 26: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/26.jpg)
describe Statement do it "logs a message when printed" do customer = Object.new logger = Object.new customer.stub(:name).and_return('Joe Customer') statement = Statement.new(customer, logger)
logger.should_receive(:log).with(/Joe Customer/) statement.print endend
![Page 27: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/27.jpg)
describe Statement do it "logs a message when printed" do customer = Object.new logger = Object.new customer.stub(:name).and_return('Joe Customer') statement = Statement.new(customer, logger)
logger.should_receive(:log).with(/Joe Customer/) statement.print endend
![Page 28: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/28.jpg)
method stubdescribe Statement do it "logs a message when printed" do customer = Object.new logger = Object.new customer.stub(:name).and_return('Joe Customer') statement = Statement.new(customer, logger)
logger.should_receive(:log).with(/Joe Customer/) statement.print endend
![Page 29: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/29.jpg)
describe Statement do it "logs a message when printed" do customer = Object.new logger = Object.new customer.stub(:name).and_return('Joe Customer') statement = Statement.new(customer, logger)
logger.should_receive(:log).with(/Joe Customer/) statement.print endend
![Page 30: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/30.jpg)
message expectationdescribe Statement do it "logs a message when printed" do customer = Object.new logger = Object.new customer.stub(:name).and_return('Joe Customer') statement = Statement.new(customer, logger)
logger.should_receive(:log).with(/Joe Customer/) statement.print endend
![Page 31: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/31.jpg)
things aren’t always as they seem
![Page 32: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/32.jpg)
describe Statement do it "uses the customer name in the header" do customer = mock("customer") statement = Statement.new(customer) customer.should_receive(:name).and_return('Joe Customer')
statement.header.should == "Statement for Joe Customer" endend
class Statement def header "Statement for #{@customer.name}" endend
![Page 33: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/33.jpg)
describe Statement do it "uses the customer name in the header" do customer = mock("customer") statement = Statement.new(customer) customer.should_receive(:name).and_return('Joe Customer')
statement.header.should == "Statement for Joe Customer" endend
class Statement def header "Statement for #{@customer.name}" endend
![Page 34: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/34.jpg)
describe Statement do it "uses the customer name in the header" do customer = mock("customer") statement = Statement.new(customer) customer.should_receive(:name).and_return('Joe Customer')
statement.header.should == "Statement for Joe Customer" endend
class Statement def header "Statement for #{@customer.name}" endend
![Page 35: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/35.jpg)
describe Statement do it "uses the customer name in the header" do customer = mock("customer") statement = Statement.new(customer) customer.should_receive(:name).and_return('Joe Customer')
statement.header.should == "Statement for Joe Customer" endend
class Statement def header "Statement for #{@customer.name}" endend
![Page 36: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/36.jpg)
describe Statement do it "uses the customer name in the header" do customer = mock("customer") statement = Statement.new(customer) customer.should_receive(:name).and_return('Joe Customer')
statement.header.should == "Statement for Joe Customer" endend
class Statement def header "Statement for #{@customer.name}" endend
messageexpectation
![Page 37: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/37.jpg)
bound to implementation
describe Statement do it "uses the customer name in the header" do customer = mock("customer") statement = Statement.new(customer) customer.should_receive(:name).and_return('Joe Customer')
statement.header.should == "Statement for Joe Customer" endend
class Statement def header "Statement for #{@customer.name}" endend
![Page 38: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/38.jpg)
describe Statement do it "uses the customer name in the header" do customer = stub("customer") customer.stub(:name).and_return('Joe Customer') statement = Statement.new(customer)
statement.header.should == "Statement for Joe Customer" endend
class Statement def header "Statement for #{@customer.name}" endend
![Page 39: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/39.jpg)
describe Statement do it "uses the customer name in the header" do customer = stub("customer") customer.stub(:name).and_return('Joe Customer') statement = Statement.new(customer)
statement.header.should == "Statement for Joe Customer" endend
class Statement def header "Statement for #{@customer.name}" endend
![Page 40: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/40.jpg)
describe Statement do it "uses the customer name in the header" do customer = stub("customer") customer.stub(:name).and_return('Joe Customer') statement = Statement.new(customer)
statement.header.should == "Statement for Joe Customer" endend
class Statement def header "Statement for #{@customer.name}" endend
![Page 41: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/41.jpg)
describe Statement do it "uses the customer name in the header" do customer = stub("customer") customer.stub(:name).and_return('Joe Customer') statement = Statement.new(customer)
statement.header.should == "Statement for Joe Customer" endend
class Statement def header "Statement for #{@customer.name}" endend
![Page 42: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/42.jpg)
describe Statement do it "uses the customer name in the header" do customer = stub("customer") customer.stub(:name).and_return('Joe Customer') statement = Statement.new(customer)
statement.header.should == "Statement for Joe Customer" endend
class Statement def header "Statement for #{@customer.name}" endend
????
![Page 43: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/43.jpg)
describe Statement do it "uses the customer name in the header" do customer = stub("customer") customer.stub(:name).and_return('Joe Customer') statement = Statement.new(customer)
statement.header.should == "Statement for Joe Customer" endend
class Statement def header "Statement for #{@customer.name}" endend
messageexpectation
![Page 44: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/44.jpg)
describe Statement do it "uses the customer name in the header" do customer = stub("customer") customer.stub(:name).and_return('Joe Customer') statement = Statement.new(customer)
statement.header.should == "Statement for Joe Customer" endend
class Statement def header "Statement for #{@customer.name}" endend
bound to implementation
![Page 45: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/45.jpg)
stubs are often used like mocks
![Page 46: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/46.jpg)
mocks are often used like stubs
![Page 47: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/47.jpg)
we verify stubs by checking state after
an action
![Page 48: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/48.jpg)
we tell mocks to verify interactions
![Page 49: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/49.jpg)
sometimes stubs just make the
system run
![Page 50: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/50.jpg)
when aremethod stubs
helpful?
![Page 51: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/51.jpg)
isolation fromnon-determinism
![Page 52: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/52.jpg)
random values
![Page 53: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/53.jpg)
random valuesclass BoardTest < MiniTest::Unit::TestCase def test_allows_move_to_last_square board = Board.new( :squares => 50, :die => MiniTest::Mock.new.expect('roll', 2) ) piece = Piece.new
board.place(piece, 48) board.move(piece) assert board.squares[48].contains?(piece) endend
![Page 54: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/54.jpg)
time
describe Event do it "is not happening before the start time" do now = Time.now start = now + 1 Time.stub(:now).and_return now event = Event.new(:start => start) event.should_not be_happening endend
![Page 55: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/55.jpg)
isolation fromexternal dependencies
![Page 56: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/56.jpg)
network access
Subject
DatabaseDatabase Interface
NetworkInterface Internets
![Page 57: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/57.jpg)
network accessdef test_successful_purchase_sends_shipping_message ActiveMerchant::Billing::Base.mode = :test gateway = ActiveMerchant::Billing::TrustCommerceGateway.new( :login => 'TestMerchant', :password => 'password' ) item = stub() messenger = mock() messenger.expects(:ship).with(item) purchase = Purchase.new(gateway, item, credit_card, messenger) purchase.finalizeend
![Page 58: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/58.jpg)
network access
Subject
StubDatabase
StubNetwork
CodeExample
![Page 59: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/59.jpg)
network access
def test_successful_purchase_sends_shipping_message gateway = stub() gateway.stubs(:authorize).returns( ActiveMerchant::Billing::Response.new(true, "ignore") ) item = stub() messenger = mock()
messenger.expects(:ship).with(item) purchase = Purchase.new(gateway, item, credit_card, messenger) purchase.finalizeend
![Page 60: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/60.jpg)
polymorphic collaborators
![Page 61: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/61.jpg)
strategies
describe Employee do it "delegates pay() to payment strategy" do payment_strategy = mock() employee = Employee.new(payment_strategy)
payment_strategy.expects(:pay) employee.pay endend
![Page 62: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/62.jpg)
mixins/pluginsdescribe AgeIdentifiable do describe "#can_vote?" do it "raises if including does not respond to birthdate" do object = Object.new object.extend AgeIdentifiable expect { object.can_vote? }.to raise_error( /must supply a birthdate/ ) end
it "returns true if birthdate == 18 years ago" do object = Object.new stub(object).birthdate {18.years.ago.to_date} object.extend AgeIdentifiable object.can_vote?.should be(true) end endend
![Page 63: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/63.jpg)
when aremessage expectations
helpful?
![Page 64: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/64.jpg)
side effectsdescribe Statement do it "logs a message when printed" do customer = stub("customer") customer.stub(:name).and_return('Joe Customer') logger = mock("logger") statement = Statement.new(customer, logger)
logger.should_receive(:log).with(/Joe Customer/) statement.print endend
![Page 65: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/65.jpg)
cachingdescribe ZipCode do it "should only validate once" do validator = mock() zipcode = ZipCode.new("02134", validator) validator.should_receive(:valid?).with("02134").once. and_return(true) zipcode.valid? zipcode.valid? endend
![Page 66: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/66.jpg)
interface discoverydescribe "thing I'm working on" do it "does something with some assistance" do thing_i_need = mock() thing_i_am_working_on = ThingIAmWorkingOn.new(thing_i_need)
thing_i_need.should_receive(:help_me).and_return('what I need') thing_i_am_working_on.do_something_complicated endend
![Page 67: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/67.jpg)
isolation testing
![Page 68: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/68.jpg)
specifying/testing individual
objects in isolation
![Page 69: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/69.jpg)
good fit with lots of little objects
![Page 70: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/70.jpg)
![Page 71: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/71.jpg)
all of these concepts apply to
the non-rails specific parts of
our rails apps
![Page 72: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/72.jpg)
isolation testing the rails-specific parts
of our applicationss
![Page 73: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/73.jpg)
![Page 74: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/74.jpg)
M
C
V
![Page 75: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/75.jpg)
ViewController
Model
![Page 76: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/76.jpg)
ViewController
Model
BrowserRouter
Database
![Page 77: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/77.jpg)
rails testing๏ unit tests
๏ functional tests
๏ integration tests
![Page 78: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/78.jpg)
rails unit tests๏ model classes (repositories)
๏ model objects
๏ database
![Page 79: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/79.jpg)
๏ model classes (repositories)
๏ model objects
๏ database
๏ views
๏ controllers
rails functional tests
![Page 80: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/80.jpg)
๏ model classes (repositories)
๏ model objects
๏ database
๏ views
๏ controllers
rails functional tests
![Page 81: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/81.jpg)
๏ model classes (repositories)
๏ model objects
๏ database
๏ views
๏ controllers
rails functional tests
!DRY
![Page 82: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/82.jpg)
rails integration tests๏ model classes (repositories)
๏ model objects
๏ database
๏ views
๏ controllers
๏ routing/sessions
![Page 83: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/83.jpg)
rails integration tests๏ model classes (repositories)
๏ model objects
๏ database
๏ views
๏ controllers
๏ routing/sessions
!DRY
![Page 84: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/84.jpg)
the BDD approach
![Page 85: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/85.jpg)
inherited from XP
![Page 86: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/86.jpg)
customer specs
developer specs
![Page 87: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/87.jpg)
![Page 88: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/88.jpg)
rails integration tests + webrat
shoulda, context, micronaut, etc
![Page 89: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/89.jpg)
customer specs are implemented as end to end tests
![Page 90: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/90.jpg)
developer specs are implemented as
isolation tests
![Page 91: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/91.jpg)
mocking and stubbingwith rails
![Page 92: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/92.jpg)
partials in view specsdescribe "/registrations/new.html.erb" do before(:each) do template.stub(:render).with(:partial => anything) end it "renders the registration navigation" do template.should_receive(:render).with(:partial => 'nav') render end it "renders the registration form " do template.should_receive(:render).with(:partial => 'form') render endend
![Page 93: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/93.jpg)
conditional branches incontroller specs
describe "POST create" do describe "with valid attributes" do it "redirects to list of registrations" do registration = stub_model(Registration) Registration.stub(:new).and_return(registration) registration.stub(:save!).and_return(true) post 'create' response.should redirect_to(registrations_path) end endend
![Page 94: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/94.jpg)
describe "POST create" do describe "with invalid attributes" do it "re-renders the new form" do registration = stub_model(Registration) Registration.stub(:new).and_return(registration) registration.stub(:save!).and_raise( ActiveRecord::RecordInvalid.new(registration)) post 'create' response.should render_template('new') end endend
conditional branches incontroller specs
![Page 95: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/95.jpg)
describe "POST create" do describe "with invalid attributes" do it "assigns the registration" do registration = stub_model(Registration) Registration.stub(:new).and_return(registration) registration.stub(:save!).and_raise( ActiveRecord::RecordInvalid.new(registration)) post 'create' assigns[:registration].should equal(registration) end endend
conditional branches incontroller specs
![Page 96: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/96.jpg)
shave a few lines but leave a little stubble
http://github.com/dchelimsky/stubble
![Page 97: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/97.jpg)
describe "POST create" do describe "with valid attributes" do it "redirects to list of registrations" do stubbing(Registration) do post 'create' response.should redirect_to(registrations_path) end end endend
stubble
![Page 98: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/98.jpg)
describe "POST create" do describe "with invalid attributes" do it "re-renders the new form" do stubbing(Registration, :as => :invalid) do post 'create' response.should render_template('new') end end it "assigns the registration" do stubbing(Registration, :as => :invalid) do |registration| post 'create' assigns[:registration].should equal(registration) end end endend
stubble
![Page 99: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/99.jpg)
chainsdescribe UsersController do it "GET 'best_friend'" do member = stub_model(User) friends = stub() friend = stub_model(User) User.stub(:find).and_return(member) member.stub(:friends).and_return(friends) friends.stub(:favorite).and_return(friend) get :best_friend, :id => '37' assigns[:friend].should equal(friend) endend
![Page 100: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/100.jpg)
chains
describe UsersController do it "GET 'best_friend'" do friend = stub_model(User) User.stub_chain(:find, :friends, :favorite). and_return(friend) get :best_friend, :id => '37' assigns[:friend].should equal(friend) endend
![Page 101: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/101.jpg)
guidlines, pitfalls, andcommon concerns
![Page 102: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/102.jpg)
focus on roles
http://www.jmock.org/oopsla2004.pdf
Mock Roles, not Objects
![Page 103: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/103.jpg)
keep things simple
![Page 104: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/104.jpg)
avoid tight coupling
![Page 105: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/105.jpg)
complex setup is a red flag for design
issues
![Page 106: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/106.jpg)
don’t stub/mock the object you’re testing
![Page 107: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/107.jpg)
impedes refactoring
![Page 108: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/108.jpg)
:refactoring => <<-DEFINITION
Improving design without changing behaviour
DEFINITION
![Page 109: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/109.jpg)
what is behaviour?
![Page 110: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/110.jpg)
![Page 111: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/111.jpg)
false positivesdescribe RegistrationsController do describe "GET 'pending'" do it "finds the pending registrations" do pending_registration = stub_model(Registration) Registration.should_receive(:pending). and_return([pending_registration]) get 'pending' assigns[:registrations].should == [pending_registration] end endend
class RegistrationsController < ApplicationController def pending @registrations = Registration.pending endend
![Page 112: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/112.jpg)
false positivesdescribe RegistrationsController do describe "GET 'pending'" do it "finds the pending registrations" do pending_registration = stub_model(Registration) Registration.should_receive(:pending). and_return([pending_registration]) get 'pending' assigns[:registrations].should == [pending_registration] end endend
class RegistrationsController < ApplicationController def pending @registrations = Registration.pending endend
![Page 113: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/113.jpg)
false positivesdescribe Registration do describe "#pending" do it "finds pending registrations" do Registration.create! Registration.create!(:pending => true) Registration.pending.should have(1).item end endend
class Registration < ActiveRecord::Base named_scope :pending, :conditions => {:pending => true}end
![Page 114: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/114.jpg)
false positivesdescribe Registration do describe "#pending" do it "finds pending registrations" do Registration.create! Registration.create!(:pending => true) Registration.pending.should have(1).item end endend
class Registration < ActiveRecord::Base named_scope :pending, :conditions => {:pending => true}end
![Page 115: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/115.jpg)
false positivesdescribe Registration do describe "#pending" do it "finds pending registrations" do Registration.create! Registration.create!(:pending => true) Registration.pending_confirmation.should have(1).item end endend
class Registration < ActiveRecord::Base named_scope :pending_confirmation, :conditions => {:pending => true}end
![Page 116: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/116.jpg)
false positivesdescribe Registration do describe "#pending" do it "finds pending registrations" do Registration.create! Registration.create!(:pending => true) Registration.pending_confirmation.should have(1).item end endend
class Registration < ActiveRecord::Base named_scope :pending_confirmation, :conditions => {:pending => true}end
![Page 117: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/117.jpg)
cucumber
![Page 118: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/118.jpg)
![Page 119: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/119.jpg)
http://pragprog.com/titles/achbd/the-rspec-book
http://www.jmock.org/oopsla2004.pdf http://www.mockobjects.com/book/
Mock Roles, not Objectsgrowing object-orientedsoftware, guided by tests
http://xunitpatterns.com/
![Page 120: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/120.jpg)
http://pragprog.com/titles/achbd/the-rspec-book
http://blog.davidchelimsky.net/http://www.articulatedman.com/
http://rspec.info/http://cukes.info/
![Page 121: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/121.jpg)
ruby frameworks
![Page 122: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/122.jpg)
rspec-mocks
http://github.com/dchelimsky/rspec
![Page 123: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/123.jpg)
mocha
http://github.com/floehopper/mocha
![Page 124: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/124.jpg)
flexmock
http://github.com/jimweirich/flexmock
![Page 125: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/125.jpg)
rr
http://github.com/btakita/rr
![Page 126: David Chelimsky Articulated Man, Incassets.en.oreilly.com/1/event/24/Don't Mock... · agenda ๏ overview of stubs and mocks ๏ mocks/stubs applied to rails ๏ guidelines and pitfalls](https://reader033.vdocuments.mx/reader033/viewer/2022050115/5f4c1c3b58aee7618f7ba74a/html5/thumbnails/126.jpg)
not a mock
http://github.com/notahat/not_a_mock