Testing & mocking¶
Lightbus provides utilities to make testing easier. These utilities allow you to:
- Ensure only specific events & RPCs were fired
- Access the sent messages
- Mock RPC responses
Mocking with events¶
from lightbus.utilities.testing import BusMocker from bus import bus def test_firing_event(): with BusMocker(bus) as bus_mock: # Setup the mocker to expect the auth.user_created was fired. # An error will be raised if the tested code fires any other events bus_mock.mock_event_firing("auth.user_created") # Run the code to be tested bus.auth.user_created.fire(field="x") # Check the event was fired once bus_mock.assert_events_fired("auth.user_created", times=1) # Get the fired event message message = bus_mock.get_event_messages("auth.user_created")[0] assert message.kwargs == {"username": "sarahjane"}
Mocking with RPCs¶
from lightbus.utilities.testing import BusMocker from bus import bus def test_calling_rpc(): with BusMocker(bus) as bus_mock: # Setup the mocker to expect the auth.user_created was fired. # An error will be raised if the tested code calls any other RPCs bus_mock.mock_rpc_call("auth.check_password", result=True) # Run the code to be tested bus.auth.check_password(username="sarahjane", password="secret") # Check the event was fired once bus_mock.assert_rpc_called("auth.check_password", times=1) # Get the fired RPC message = bus_mock.get_rpc_messages("auth.check_password")[0] assert message.kwargs == {"username": "sarahjane", "password": "secret"}
Allowing arbitrary events and RPCs¶
By default the mocker will raise an error if any event or RPC is fired or called which has
not be setup using the mock_event_firing
/ mock_rpc_call
methods.
You can disable this and therefore allow any events or RPCs to the fired/called by using
BusMocker(bus, require_mocking=False)
.
For example, the following will result in no errors even though we have not setup any mocks:
from lightbus.utilities.testing import BusMocker from bus import bus def test_permissive_mocking(): with BusMocker(bus, require_mocking=False) as bus_mock: # Neither will cause an error despite the lack of mocking setup. # This is because we have set require_mocking=False bus.auth.user_created.fire(field="x") bus.auth.check_password(username="sarahjane", password="secret")
The @bus_mocker
decorator¶
You can also access the bus mocker using the @bus_mocker
decorator. We can rewrite
our earlier event example (above) as follows:
from lightbus.utilities.testing import bus_mocker from bus import bus @bus_mocker(bus) def test_firing_event(bus_mock): # Setup the mocker to expect the auth.user_created was fired. # An error will be raised if the tested code fires any other events bus_mock.mock_event_firing("auth.user_created") # Run the code to be tested bus.auth.user_created.fire(field="x") # Check the event was fired once bus_mock.assert_events_fired("auth.user_created", times=1) # Get the fired event message message = bus_mock.get_event_messages("auth.user_created")[0] assert message.kwargs == {"username": "sarahjane"}
Testing in Django¶
You can use the mocker in your Django tests just as shown above. For example, we can access the mocker using the context manager:
from django.test import TestCase from lightbus.utilities.testing import BusMocker from bus import bus class ExampleTestCase(TestCase): def test_something(self): with BusMocker(bus, require_mocking=False) as bus_mock: ...
Or we can use the @bus_mocker
decorator:
from django.test import TestCase from lightbus.utilities.testing import bus_mocker from bus import bus class ExampleTestCase(TestCase): @bus_mocker(bus) def test_something(self, bus_mock): ...