I'm currently building myself a personal cli, which helps me integrate coded automation into my daily routines. After some experiments, I though that my next implementation could be here to stay. That's why I started with TDD and after some coding I ended up with the following test for the entrypoint of my typer-app.
@patch("main.get_config")
@patch("main.get_action_factory")
def test_create_action_with_factory(create_action_factory, get_config_mock):
# Given
action_factory_mock = MagicMock(spec=ActionFactory)
create_action_factory.return_value = action_factory_mock
config_service = ConfigService(action_path=DirectoryPath())
get_config_mock.return_value = config_service
# When
result = runner.invoke(app, ["create-action", "new-action"])
# Then
result.exit_code == 0
create_action_factory.assert_called_once_with(config_service.action_path)
action_factory_mock.create_action.assert_called_once_with("new-action")
I thought it was a good to idea to let the shell entrypoint handle all the linking together, but there is a lot to mock. All this to answer whether the action_factory was called correctly.
So it's time to let the tests drive the design. I decided to pull out the service creation into a service factory.
After four commits I get the following code change
- action_factory = get_action_factory(get_config().action_path)
+ action_factory = get_action_factory()
which allowed simpler test:
@patch("main.get_action_factory")
def test_create_action_with_factory(create_action_factory):
# Given
action_factory_mock = MagicMock(spec=ActionFactory)
create_action_factory.return_value = action_factory_mock
# When
result = runner.invoke(app, ["create-action", "new-action"])
# Then
result.exit_code == 0
action_factory_mock.create_action.assert_called_once_with("new-action")
Looks way better. I'll follow up with some more coding done. Let's see what other decisions the tests designed.
Top comments (0)