Skip to content

Instantly share code, notes, and snippets.

@vsavkin
Created March 4, 2012 22:01
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vsavkin/1975016 to your computer and use it in GitHub Desktop.
Save vsavkin/1975016 to your computer and use it in GitHub Desktop.
Refactored sell_book
def sell_book
@book = Book.find(params[:id])
BookSellingService.sell_book(@book)
end
@Bartuz
Copy link

Bartuz commented Nov 1, 2015

Sorry for writing here but comments under the post are disabled.

You wrote comment to this snippet:

The controller is easier to test. When before we would have to have two tests, after our change is done we need only one.

How test for this action would look like? Do you just assert that BookSellingService received sell_book message with proper book?

describe 'GET #sell_book' do
  let(:book) { create(:book) }
  it 'calls selling book service (which is dependency of this controller, right?)' do
    get :sell_book, id: book.id
    expect(BookSellingService).to receive(:sell_book).with(book)
  end
end

Is that sufficient enough? (assuming you have unit tests for BookSellingService ).

Other scenario I'm thinking of is writing: receive(:sell_book).with(book).and_call_original?. But in that case I would have stub any dependencies of BookSellingService, is that right?

Let's say that BookSellingService uses courier (e.g. FedEx) API and needs to call it.
In that case would we have to add before { allow(FedEx).to receive(:ship!).and_return (true) } to this test case? IMHO controller test for this action shouldn't have any idea of internal BookSellingService implementation but I'm not highly concerned about it.

How would you write test for it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment