simulated objects that mimic the behavior of real objects in controlled ways
Read: https://8thlight.com/blog/uncle-bob/2014/05/14/TheLittleMocker.html
Mock objects are meant to improve the expressiveness of code while reducing coupling
Do not mock any class you do not own. In fact, do not unit test any code that you do not 100% own.
Basically, if your code has a dependency that you don’t control, then you shouldn’t mock it because you can’t guarantee the interface will remain constant.
TDD is just as much about design that is is about test, when mocking an external API the test cannot be used to drive the design, the API belongs to someone else ; this third party can and will change the signature and behaviour of the API.
https://vimeo.com/80533536
I see strong correlation between high number of integration tests and design problems
describe UmbrellaAssistant do
it "asks whether service if it would be rainy" do
whether_service = double
assistant = UmbrellaAssistant.new(whether_service: whether_service)
assistant.should_i_take_umbrella?
expect(whether_service).to have_received(:will_be_rainy?)
end
enddescribe UmbrellaAssistant do
it "returns true if it will be rainy" do
whether_service = double
allow(whether_service).to receive(:will_be_rainy?).and_return(true)
assistant = UmbrellaAssistant.new(whether_service: whether_service)
expect(assistant.should_i_take_umbrella?).to be_true
end
it "returns false if it won't be rainy" do
whether_service = double
allow(whether_service).to receive(:will_be_rainy?).and_return(false)
assistant = UmbrellaAssistant.new(whether_service: whether_service)
expect(assistant.should_i_take_umbrella?).to be_false
end
endThe real benefit of isolated tests (...) is that those tests puts tremendous pressure on our designs
http://blog.plataformatec.com.br/2015/10/mocks-and-explicit-contracts/
https://8thlight.com/blog/eric-smith/2011/10/27/thats-not-yours.html
Rubytapas #287, #289, #296, #312