Jamesla
Jamesla

Reputation: 1408

How to create stub methods in rails 5 and minitest

I have the following code and I am trying to create a stub for it so I can place tests without it making a real order.

def order
    client = StraightServerKit::Client.new(
        gateway_id: "123",
        secret: "123"
    )
    o = StraightServerKit::Order.new(amount: 1)
    mycelium_order = client.orders.create(o)
end

How do I stub the create method? This is my attempt but it doesn't call the stubbed method and tries to make a real api call (this method => client.orders.create(o))

test "should create order" do
  mock = Minitest::Mock.new
  def mock.apply; true; end

  client =  StraightServerKit::Client.new(
    gateway_id: "xxx",
    secret: "xxx"
  )

  client.orders.stub :create, mock do
  {
    return_data = "data"
  }

  post post_order_path, params: { order: { amount: 10 } }
  assert_response :success
end

METHOD1

Have updated using the stub_any_instance gem but still not working due to the method being nested

require 'minitest/stub_any_instance'
test "should create order" do
    client = StraightServerKit::Client.new(
      gateway_id: "asdf",
      secret: "asdf"
    );
    client.stub_any_instance(:order, "data")

    post post_order_path, params: { order: { amount: 10 } }
    assert_response :success

  end

Error: DashboardControllerTest#test_should_create_order: NoMethodError: undefined method `stub_any_instance' for # (although stub_any_instance works fine with stubbing String.length)

METHOD2:

require 'mocha/mini_test'
test "should create order" do
    StraightServerKit::Client.any_instance.stubs(:new).returns("test")

    post post_order_path, params: { order: { amount: 10 } }
    assert_response :success
  end

this loads the real implementation rather than the stub

METHOD3:

test "should create order" do
    StraightServerKit::Client.stub_any_instance(:new, "data")

    post post_order_path, params: { order: { amount: 10 } }
    assert_response :success
  end

DashboardControllerTest#test_should_create_order: NameError: undefined method new' for classStraightServerKit::Client'

Upvotes: 2

Views: 2263

Answers (1)

igneus
igneus

Reputation: 992

The test seems to be a controller test. You first build a client in your test and stub it's method. The method is stubbed only on this particular instance, not on all instances of StraightServerKit::Client.

Then you call a controller action which creates it's own client, so the stub you created isn't used at all.

You can use minitest-stub_any_instance gem, which allows you to stub any instance of a class:

StraightServerKit::Client.stub_any_instance(:order, 'data')

Upvotes: 1

Related Questions