Ctpelnar1988 Ctpelnar1988 - 7 months ago 15
Ruby Question

MiniTest::Assertions returning false for test that should be returning true

I am attempting to learn MiniTest and by doing so I have started testing one of my applications that uses the PayPal API to approve/deny credit-card payments. Below is my attempt at testing the purchase method inside the Payment class. (credit_card was originally a private method, moved to public for testing)

payment.rb

require "active_merchant/billing/rails"

class Payment < ActiveRecord::Base
belongs_to :order
attr_accessor :card_number, :card_verification

def purchase(card_info, billing_info)
if credit_card(card_info).valid?
response = GATEWAY.purchase(price_in_cents, credit_card(card_info), purchase_options(billing_info))
@paypal_error = response.message
response.success?
end
end

def price_in_cents
(@total.to_f * 100).round
end


def credit_card(card_info)
@credit_card ||= ActiveMerchant::Billing::CreditCard.new(card_info)
end

private

def purchase_options(billing_info)
billing_info
end

end


payment_test.rb

require 'test_helper'
require "active_merchant/billing/rails"

class PaymentTest < ActiveSupport::TestCase
setup do
@card_info = {
brand: "Visa",
number: "4012888888881881",
verification_value: "123",
month: "01",
year: "2019",
first_name: "Christopher",
last_name: "Pelnar",
}
@purchase = Payment.new
end

test "purchase" do
assert @purchase.credit_card(@card_info).valid?, true
end

end


Error message after running
rake test
:


--------------------------
PaymentTest: test_purchase
--------------------------
(0.1ms) ROLLBACK
test_purchase FAIL (0.02s)
Minitest::Assertion: true
test/models/payment_test.rb:20:in `block in <class:PaymentTest>'


Finished in 0.03275s
1 tests, 1 assertions, 1 failures, 0 errors, 0 skips

Answer

MiniTest::Assertions assert method call uses the syntax assert(test, msg = nil) The reason your test is returning true is that is the message you chose to use. The assert_equal method takes 2 values to compare. Also, instead of making the private method public, you can use the .send method like this:

assert @purchase.send(:credit_card,@card_info).valid?

Also, change the setup to a function definition:

def setup
  # setup logic
end

To make the output more verbose (capture the ActiveMerchant errors), try the following:

test "purchase" do
  credit_card = @purchase.send(:credit_card, @card_info)
  assert credit_card.valid?, "valid credit card"
  puts credit_card.errors unless credit_card.errors.empty?
end

Reading rubyforge API I think the credit card type should be set to bogus in testing.