2015-02-22 2 views
0

Я пишу спецификацию для обратного вызова after_create. Спецификация выглядит следующим образом:Assert Издание Redis

it 'broadcasts creation' do 
    message = Message.create(body: 'foo') 
    expect(Redis.any_instance).to have_received(:publish) 
end 

Моей Message модель выглядит следующим образом:

class Message < ActiveRecord::Base 
    after_create -> { publish(:create) } 

    private 

    def publish(name) 
    Redis.new.publish(
     self.class.inferred_channel_name, 
     json(action) 
    ) 

    Redis.new.publish(
     inferred_channel_name_for_single_record, 
     json(action) 
    ) 

    puts 'published!' 
    end 
end 

Я знаю, что обратный вызов работает, потому что я печать «опубликовал» в конце, и я проверил, что Redis действительно публикует что-то дважды.

Тем не менее, моя спекуляция терпит неудачу со следующим сообщением:

1) Message Methods #entangle without options broadcasts creation 
Failure/Error: expect(Redis.any_instance).to have_received(:publish) 
    unstubbed, expected exactly once, not yet invoked: #<AnyInstance:Redis>.publish(any_parameters) 
# ./spec/models/message_spec.rb:20:in `block (5 levels) in <top (required)>' 

Я использую bourne с мокко использовать have_received Искателя.

Как я могу пройти этот тест?

ответ

2

Создать макет для Redis и гасит методы класса и экземпляра - new и publish, соответственно.

it "broadcasts creation" do 
    redis = stub_redis 

    Message.create(body: "foo") 

    expect(redis).to have_received(:publish).twice 
end 

def stub_redis 
    mock("redis").tap do |redis| 
    redis.stubs(:publish) 
    Redis.stubs(:new).returns(redis) 
    end 
end 
+0

Я бы отметил, что есть камень mock_redis, который делает эту работу тривиальной. –

1

Вы можете попытаться использовать макет expect_any_instance_of.

it 'broadcasts creation' do 
    expect(Redis.any_instance).to receive(:publish).twice 
    message = Message.create(body: 'foo') 
end 

https://www.relishapp.com/rspec/rspec-mocks/v/3-2/docs/working-with-legacy-code/any-instance

+0

Похоже, это на самом деле не позволяет мне использовать 'has_received', только' should_receive' ... Или я делаю что-то неправильно? – weltschmerz

+0

Код, который я опубликовал, не проверен, поэтому нет, вы, вероятно, не делаете ничего плохого. Попробуйте отредактированную версию, которая сначала устанавливает ожидаемое, а затем запускает код для его использования. – messanjah

Смежные вопросы