user98651
user98651

Reputation: 324

Ruby rspec Mocking a class

I have a file with two classes in it.

class LogStash::Filters::MyFilter< LogStash::Filters::Base

and

class LogStash::JavaMysqlConnection

JavaMysqlConnection has methods initialize and select. It is in use by the MyFilter class, and is used to query the database as you may have guessed.

How do I mock the initialize and select methods to return nil and an array respectively?

I tried using:

before(:each) do
  dbl = double("LogStash::JavaMysqlConnection", :initialize => nil)
end

but this did not work, as I am still seeing a communication link failure.

I have rspec version 2.14.8

Thanks in advance. PS. I am new to Ruby

Upvotes: 9

Views: 17678

Answers (3)

Andrey Deineko
Andrey Deineko

Reputation: 52367

Bad (working): Read more as to why exactly it is a bad practice

allow_any_instance_of(LogStash::JavaMysqlConnection)
  .to receive(:select)
  .and_return([])

Good:

let(:logstash_conn) { instance_double(LogStash::JavaMysqlConnection) }

allow(LogStash::JavaMysqlConnection)
  .to receive(:new)
  .and_return(logstash_conn)

allow(logstash_conn)
  .to receive(:select)
  .and_return([])

Docs

RSpec

Upvotes: 14

nikolayp
nikolayp

Reputation: 17949

Using RSpec stub_const

describe 'No User' do
  let(:user)       { double }
  let(:attributes) { { name: 'John' } }

  before do
    stub_const 'User', instance_double('User', new: user)
  end

  it 'creates user' do
    expect(user).to receive(:update!).with(attributes)

    User.new.update!(attributes)
  end
end

Upvotes: 3

user98651
user98651

Reputation: 324

Following on from Andrey's response, the solution that worked for me was:

 before(:each) do
    mock_sql = double(:select=> sql_select_return)
    allow(LogStash::JavaMysqlConnection).to receive(:new).and_return(mock_sql)
end

Upvotes: 3

Related Questions