Project

tzu_mock

0.01
Low commit activity in last 3 years
A long-lived project that still receives updates
Simple library for mocking Tzu in RSpec
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Runtime

 Project Readme

Tzu Mock

A very simple library for mocking Tzu in RSpec

Usage

TzuMock.success(klass).returns(result) #=> Successful Outcome
TzuMock.invalid(klass).returns(error) #=> Invalid Outcome
TzuMock.failure(klass).returns(error) #=> Failed Outcome

Consider this Tzu command:

class UpdateUser
  include Tzu
  include Tzu::Validation

  def call(params)
    raise ArgumentError.new('I should be mocked!')
  end
end

There are two ways this might need to be mocked. The first happens when the Tzu command is invoked without a block:

outcome = UpdateUser.run(params)

The second is when the command is invoked with a block, as in this mock controller:

class MockController
  attr_reader :method_called

  def update(params = {})
    UpdateUser.run(params) do
      success do |result|
        @method_called = :success
      end

      invalid do |error|
        @method_called = :invalid
      end

      failure do |error|
        @method_called = :failure
      end
    end
  end
end

In both cases, the use of TzuMock is the same. First, we'll mock at the simple invocation:

describe UpdateUser do
  let(:result) { 'Desired Result' }
  let(:error) { { error: 'ERROR' } }
  let(:params) { { last_name: 'Turner' } }

  context 'success' do
    before { TzuMock.success(UpdateUser).returns(result) }

    let(:outcome) { UpdateUser.run(params) }

    it 'mocks a successful outcome and allows parameters to be verified' do
      expect(outcome.success?).to be true
      expect(outcome.result).to eq result
      expect(outcome.type).to be nil
      expect(UpdateUser).to have_received(:run).with(params)
    end
  end

  context 'invalid' do
    before { TzuMock.invalid(UpdateUser).returns(error) }

    let(:outcome) { UpdateUser.run(params) }

    it 'mocks an invalid outcome and allows parameters to be verified' do
      expect(outcome.success?).to be false
      expect(outcome.result).to eq error
      expect(outcome.type).to eq :validation
      expect(UpdateUser).to have_received(:run).with(params)
    end
  end

  context 'failure' do
    before { TzuMock.failure(UpdateUser).returns(error) }

    let(:outcome) { UpdateUser.run!(params) }

    it 'mocks a failed outcome and allows parameters to be verified' do
      expect(outcome.success?).to be false
      expect(outcome.result).to eq error
      expect(outcome.type).to eq :execution
      expect(UpdateUser).to have_received(:run!).with(params)
    end
  end
end

TzuMock mocks both run and run!, and spies on the class so that you can verify the parameters that were passed.

Next, we'll mock the controller:

describe UpdateUser do
  let(:result) { 'Desired Result' }
  let(:error) { { error: 'ERROR' } }
  let(:params) { { last_name: 'Turner' } }

  let(:controller) { MockController.new }

  context 'success' do
    before { TzuMock.success(UpdateUser).returns(result) }

    it 'mocks a successful outcome and allows parameters to be verified' do
      controller.update(params)
      expect(UpdateUser).to have_received(:run).with(params)
      expect(controller.method_called).to eq :success
    end
  end

  context 'invalid' do
    before { TzuMock.invalid(UpdateUser).returns(error) }

    it 'mocks a successful outcome and allows parameters to be verified' do
      controller.update(params)
      expect(UpdateUser).to have_received(:run).with(params)
      expect(controller.method_called).to eq :invalid
    end
  end

  context 'failure' do
    before { TzuMock.failure(UpdateUser).returns(error) }

    it 'mocks a successful outcome and allows parameters to be verified' do
      controller.update(params)
      expect(UpdateUser).to have_received(:run).with(params)
      expect(controller.method_called).to eq :failure
    end
  end
end

TzuMock effortlessly passes your desired outcome to the appropriate block.

Hash Result

TzuMock converts your result hash attributes into methods by default.

# if you return this result
before { TzuMock.success(UpdateUser).returns({name: 'me'}) }

# you can access it on this way
outcome = UpdateUser.run(params)
outcome.result.name

# even if you have result as array contains hashs
before { TzuMock.success(UpdateUser).returns([{name: 'me'}]) }

# you can access it on this way
outcome = UpdateUser.run(params)
outcome.result.first.name

Configuration

By default, TzuMock mocks the run and run! methods, but you can add more methods to that list if your Tzu classes have another interface.

# spec/spec_helper.rb
TzuMock.configure { |config| config.stub_methods = [:go, :go!] }