Skip to content
This repository was archived by the owner on Nov 24, 2020. It is now read-only.

Implement mox#10

Open
idlehands wants to merge 2 commits into
Nitro:masterfrom
idlehands:implement_mox
Open

Implement mox#10
idlehands wants to merge 2 commits into
Nitro:masterfrom
idlehands:implement_mox

Conversation

@idlehands

Copy link
Copy Markdown

Mox is a mocking library created by Jose Valim. It's coolest feature is that it breaks if you try to mock something that doesn't have a behavior or if you try to mock a function that doesn't exist. It helps things be a little more readable by allowing you to define the functions in the test themselves, so everything is a little less mysterious.

You could move the mock definition (with multiple clauses for the anonymous functions) up into a setup block. I prefer to be more explicit. Additionally, you can mock (set an expectation of a call received) the calls with the library, but, in this case, they are queries, not commands, so I left them as stubs.

I've switched the MockSessionService to use that library.

use Elixometer

@behaviour SessionService
@callback validate_api_token(String.t()) :: Tuple.t()

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the only reason for a behaviour is for testing, it's pretty common (and acceptable) to move the callbacks/behaviour definition into the module that implements it in prod.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is super useful because I didn't know about Mox and so I'll definitely check it out. I'm a little lost about how it works ATM moment but I'm sure some reading will clear it up.

In this case we only had one implementation and a mock, but this module is not that generic and the idea was that people could provide their own implementation of a SessionService if they needed to handle it differently. Given that I'd like to support that, but that also nobody else seems to be interested, I'm on the fence about merging.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, not a problem. I will update the PR to leave the callback in the SessionService behaviour. That is technically a cleaner implementation and definitely the way to go if you want the interface behaviour for more than just testing. Mox will work just fine that way, too.

result

{:error, type, code, error} ->
{:error, type, code, error} when is_binary(error) ->

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding the guard clause allows us to treat this as a separate case instead of nesting flow control.


{:ok, %HTTPoison.Response{status_code: code, body: body}} when code >= 400 and code <= 499 ->
{:ok, %HTTPoison.Response{status_code: code, body: body}}
when code >= 400 and code <= 499 ->

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry. This is from the 1.6.4 formatter. I can remove it if you want, but I recommend updating and starting to use the formatter.

Comment thread mix.exs
:elixometer
],
mod: {Spacesuit, []}
mod: {Spacesuit, []},

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As of 1.4(?) you no longer want to explicitly pass applications that need to be started. While this kind of sucks since it takes away the explicitness, it means that you can't mess up by forgetting to add a new application to the list when you start using it. In my case, I needed to clean this up or mox wasn't getting started.

@@ -1,91 +1,167 @@
defmodule SpacesuitAuthMiddlewareTest do
use ExUnit.Case
import Mox

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

importing gives us mock and stub as local functions. If you prefer it to be more explicit, you can require Mox and the calls will be Mox.mock and Mox.stub.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants