Richard VanBreemen
Richard VanBreemen

Reputation: 573

Having test coverage problems with Rails instance method in model with Stripe

I'm using the Simplecov gem to output my test coverage and for an odd reason can not get 2 lines in my Rails instance method in my model to be captured. Also, any insight into why Simplecov states that the entire method is covered except for the 2 lines when I have not even included a describe block within my specs would be great as well. Any help would be greatly appreciated.

def process
  if valid?
    payment = Stripe::Charge.create(amount: amount, currency: "usd",
                                    card: stripe_card, capture: false)

    if (payment[:card][:address_line1_check] &&
        payment[:card][:cvc_check] &&
        payment[:card][:address_zip_check]).eql?("pass")
      charge = Stripe::Charge.retrieve(payment[:id]) # This line is not captured
      charge.capture # This line is not captured
    end

    self.transaction_number = payment.id
    save!
  end
end

Upvotes: 0

Views: 226

Answers (1)

threedaymonk
threedaymonk

Reputation: 525

Simplecov is showing you two things:

  1. At least once during the test run, process is called.
  2. At no point during the test run does the condition of the if statement evaluate to a truthy value; consequently, the body of the statement is never reached.

Simplecov doesn't care whether you explicitly created a describe block: Simplecov simply looks at which statements were executed during the test run.

Separately, I don't think the logic of your if condition does what you expect (and using eql? is not very idiomatic).

if (payment[:card][:address_line1_check] &&
    payment[:card][:cvc_check] &&
    payment[:card][:address_zip_check]).eql?("pass")

Each of these values can be one of {nil, "pass", "fail", "unchecked"}. A string value is truthy: "a" && "b" == "b" but nil && "b" == nil. Your code could be executed even if address_line1_check were "fail".

If you want to test that all three values are equal to "pass", this will do it:

if [payment[:card][:address_line1_check],
    payment[:card][:cvc_check],
    payment[:card][:address_zip_check]].all? { |v| v == "pass" }

Upvotes: 2

Related Questions