How do I mock and verify an ActionCable transmission in minitest?
Asked Answered
H

2

11

I'm using Ruby on Rails 5.1 with ActionCable. I would like to use minitest to test a particular method, and mock the "ActionCable.server.broadcast" call to verify I'm sending out the right data I have

module MyModule
  class Scanner

    def trasmit
    ...
        ActionCable.server.broadcast "my_channel", data: msg_data

but I don't know how in my minitest class I can verify that the ActionCable broadcast the correct message data.

Hirsute answered 20/4, 2018 at 15:16 Comment(0)
F
6

Rails ActionCable source is already well enough tested to ensure it works, so we know that broadcasting work if we just call ActionCable with the right parameters.

If you have a socket-heavy application I recommend trying out action-cable-testing which has lots of helper to verify that ActionCable actually broadcasts something.

You can check if your method broadcasts X times to a specific channel:

class ScannerTest < ActionDispatch::IntegrationTest
    include ActionCable::TestHelper

    def test_my_broadcaster
       channel_name = 'my_channel'
       assert_broadcasts channel_name, 0

       # run your method (e.g. trasmit)
       assert_broadcasts channel_name, 1
    end
end

Or verify that the expected data was sent to the channel:

class ScannerTest < ActionDispatch::IntegrationTest
    include ActionCable::TestHelper

    def test_my_broadcaster
       channel_name = 'my_channel'
       expected_data = { :hello => "world" }
       assert_broadcast_on(channel_name, data: expected_data) do
          # run your trasmit method here which should call:
          ActionCable.server.broadcast channel_name, data: expected_data 
       end
    end
end

This Gem might be part of the Rails core soon so it's definitely worth a look especially if you are testing other parts of ActionCable which sooner or later might be too much work to mock. (E.g. sign in with a specific user).

Fishtail answered 24/4, 2018 at 15:37 Comment(0)
B
2

I suggest using mocks (I use the mocha gem for mocking) to test the broadcast. Here is a simple example:

channel_name = 'my_channel'
msg_data = 'hello'

broadcast = mock
server = mock
server.expects(:broadcast).with(channel_name, data: msg_data).returns(broadcast)

ActionCable.expects(:server).returns(server)

This way you are mocking all ActionCable.server calls but are testing that they are called with the right parameters.

Buckeen answered 23/4, 2018 at 15:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.