0

Let's say I have a database to store the data of people (name, email). And there's an update method in the controller. The method is like:

  def update
    @people = People.find(params[:id])
    if @people.update(people_params)
       redirect_to people_path
    else
       render 'edit'
    end
  end

I wonder how can I test the situation that the update failed? Or do I really need to test it? I have searched it on StackOverflow, there is a link about it, but it not says if I should or should not to test it. Could anyone give me some help about it? If it can be test, how? Thank you so much!

Meilan
  • 434
  • 6
  • 17

2 Answers2

1
  1. You don’t need to test Ruby and Rails internals. Either you trust both of them do work as expected, or you’d better switch to some other language / framework.

  2. Whether you still want to test it, mock everything unrelated. Here is an example of doing this with rspec and flexmock.

describe '#update' do
  let(:person) { build(:people) }
  before do
    flexmock(People).should_receive(:find).once.returns person
    flexmock(person).should_receive(:update).once.returns false
  end

  it 'redirects to `edit` page' do
    ...
  end
end
Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160
  • I agree he shouldn't test rails internals, but in theory he should test behavior no? the redirection if update succeeds vs the rendering if it didn't. – Joel Blum Apr 10 '20 at 05:56
  • This is testing whether `if` works as expected. It does. I swear. – Aleksei Matiushkin Apr 10 '20 at 05:57
  • what is the code has a mistake and it redirects_to peple_path instead of people_path? you're saying this shouldn't be covered.. – Joel Blum Apr 10 '20 at 05:58
  • @Joel_Blum what if in your test you’d make _the same mistake_ and `peple_path` also existed? There is a borderline between common sense and 100% coverage. I am not advocating this, and my answer shows _how_ actually one could test it. I personally would not waste time on producing tests like this. – Aleksei Matiushkin Apr 10 '20 at 06:11
  • lol if peple_path also exists AND the test makes the same mistake we're indeed in a bit of a jam. quite unlikely though :) – Joel Blum Apr 10 '20 at 06:20
  • 1
    I realize I'm an outlier here, but sometimes I end up testing Rails internals just to make sure that my understanding of how they work is actually how they work. I'm not too smart, so I often get it wrong! I sleep better when I test rather than assume I know how it works. – Les Nightingill Apr 11 '20 at 00:23
0

Typically the update failure would be due to object to be saved not being valid, according to its validation criteria. You would normally test the validation criteria in the model specs, but when testing the controller, or in integration tests, you might want to ensure that the #edit render occurs when the user tries to save an invalid model.

If the model does not have any validation criteria, you can probably skip the else render :edit altogether. It's part of the Rails scaffold that may not apply in all cases.

You can test your update fail scenario by trying to save an invalid model. You would typically confirm that the user was correctly informed of the validity problem (flash message).

There's no right or wrong as to whether or not to test. Personally, I would test it, b/c I like TDD, and I prefer to over-test rather than under-test. Many would not.

Les Nightingill
  • 5,662
  • 1
  • 29
  • 32