Home > Software design >  how to use Minitest to handle a json input for record changes
how to use Minitest to handle a json input for record changes

Time:11-28

The following two separate tests are handling their respective json string

    assert_no_difference('Article.count') do
      post array_api_v1_articles_path, params: @existing, as: :json
    end
{ "items": { [
  { code: "00083", "sell_price": 0.01 }, ...
] } }

    assert_changes articles(:fifty_five).sell_price, from: 9.99, to: 0.01 do
      post array_api_v1_articles_path, params: @existing, as: :json
    end  

{ "items": { [
  { code: "00084", "sell_price": 0.01 }, ...
] } }

While the former case can measure the change in count, the latter - while returning the new value with puts commands in the method reflects the change

puts @article.sell_price
0.01

, the asserts fails: 0.999e1 didn't change. Expected 9.99 to not be equal to 9.99.

How should this test be cast then?

CodePudding user response:

Through trial and error

assert_changes articles(:fifty_five).reload.sell_price [...] do
assert_changes articles(:fifty_five).sell_price [...] do

blocks never worked. It seems the block is the issue. A pithier

post array_api_v1_articles_path, params: @params, as: :json
assert_equal 0.01, articles(:fifty_five).reload.sell_price

generates the assertion with success. reload the fixture...

CodePudding user response:

You need to wrap the condition in a lamdba:

article = articles(:fifty_five)
assert_changes ->{ article.sell_price }, from: 9.99, to: 0.01 do
  post array_api_v1_articles_path, params: @existing, as: :json
  article.reload
end

This lambda will be evaluated before and after the block is run.

What you're doing is passing the instance of Float (or Decimal if you're doing it right) which doesn't actually change. Numerics are actually immutable.

While you can use assert_equal the failure message is a lot less useful.

  • Related