Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Stubs and mocks

Krzysztof
December 21, 2023

Stubs and mocks

A quick presentation about the differences between stubs and mocks, with examples and explanations.

Krzysztof

December 21, 2023
Tweet

More Decks by Krzysztof

Other Decks in Programming

Transcript

  1. TestDouble (1/1) Stuby i Mocki are TestDoubles Fundamental part of

    TDD, one of BetterSpecs directives mentioned couple times, impotant in Martina Fowler’s articles about tests
  2. Mock (2/1) Mock in RSpec usually looks like: expect(some_object).to receive(some_method).and_return(some_value)

    If some_object does not receive some_method then the test fails. Same if it does not return some_value. We could add receive(some_method).with(arg: ugment) to be more precise with what we expect from our mock. Other testing framework albo have build in mocks, like MiniTest stuff = MiniTest::Mock.new stuff.expect :thing?, true service = MyService.new(stuff) service.call stuff.verify If MyService calls thing? on stuff tests succeeds. If it does not call, then it fails.
  3. Stub (3/1) Simple Stub w RSpec is usually: allow(some_object).to receive(some_method).and_return(some_value)

    Time.stub :now, Time.new(2023, 03, 07).utc do MyObject.new.are_we_there_yet? end MiniTest, closer to pure ruby’ego we can for example: Method now is stubbed on Time object and durin the testing of MyObject we will always get now with the same value (when we call are_we_there_yet? whic calls Time.now we will get the value of Time.new(2023, 03, 07).utc)
  4. Mock vs Stub (4/1) Summary of the difference expect(some_object).to receive(some_method).and_return(some_value)

    allow(some_object).to receive(some_method).and_return(some_value) Mock: Stub: Monitors the object as instructed, throws an error if the expectations are not met. It can replace a value for what it monitors. Mainly used to double objects, when we mostly care about the output, although checking the input can also be a part of the mock. Replaces an object or its part as instructed. Bends the behaviour of the stubbed object for the needs of the test. Mostly used to double an object, where me mostly care about the input, due to behaviour modifications. Output is also important, but it is tested on a stub.
  5. Mock & Stub (5/1) We can join them together, giving

    us simplified and faster test structures: Mock that returns a stub (RSpec) mock_object = MiniTest::Mock.new mock_object.expect :list_all, [] Client::Request.stub :new, mock_client do # do something using the mocked object end The same idea, mock returns a stub (MiniTest)
  6. Stub Pure Ruby (5/1) company = Company.create(name: "2N") def company.active?;

    true; end def company.add_employee(*args); raise PolicyError::NotAuthorized; end If we do: company2 = Company.create(name: ‘Black Mesa’) then the values won’t get stubbed. On company variable they will stay stubbed