|
1 | | -defmodule VBT.Aws.Test do |
2 | | - @moduledoc """ |
3 | | - Helpers for testing AWS interaction. |
4 | | -
|
5 | | - ## Usage |
6 | | -
|
7 | | - # test_helper.exs |
8 | | - VBT.Aws.Test.setup() |
9 | | -
|
10 | | - # some_test.exs |
11 | | - test "..." do |
12 | | - VBT.Aws.Test.stub_request(response) |
13 | | -
|
14 | | - assert perform_aws_operation(...) == {:ok, response} |
15 | | -
|
16 | | - assert_received {:aws_request, req, config} |
17 | | - # do something with req and config |
18 | | - end |
19 | | - """ |
20 | | - |
21 | | - @doc """ |
22 | | - Sets up test mock which implements `ExAws.Behaviour`. |
23 | | -
|
24 | | - Invoke this function in test_helper.exs to setup the mock. Then, in your tests you can use |
25 | | - `stub_request/1`. If you need a finer grained control, you can also use `Mox`. See |
26 | | - `stub_request/1` for details. |
27 | | - """ |
28 | | - @spec setup :: :ok |
29 | | - def setup do |
30 | | - Application.put_env(:vbt, :ex_aws_client, VBT.TestAwsClient) |
31 | | - mox().defmock(VBT.TestAwsClient, for: ExAws.Behaviour) |
32 | | - :ok |
| 1 | +if Code.ensure_loaded?(Mox) do |
| 2 | + defmodule VBT.Aws.Test do |
| 3 | + @moduledoc """ |
| 4 | + Helpers for testing AWS interaction. |
| 5 | +
|
| 6 | + ## Usage |
| 7 | +
|
| 8 | + # test_helper.exs |
| 9 | + VBT.Aws.Test.setup() |
| 10 | +
|
| 11 | + # some_test.exs |
| 12 | + test "..." do |
| 13 | + VBT.Aws.Test.stub_request(response) |
| 14 | +
|
| 15 | + assert perform_aws_operation(...) == {:ok, response} |
| 16 | +
|
| 17 | + assert_received {:aws_request, req, config} |
| 18 | + # do something with req and config |
| 19 | + end |
| 20 | + """ |
| 21 | + |
| 22 | + @doc """ |
| 23 | + Sets up test mock which implements `ExAws.Behaviour`. |
| 24 | +
|
| 25 | + Invoke this function in test_helper.exs to setup the mock. Then, in your tests you can use |
| 26 | + `stub_request/1`. If you need a finer grained control, you can also use `Mox`. See |
| 27 | + `stub_request/1` for details. |
| 28 | + """ |
| 29 | + @spec setup :: :ok |
| 30 | + def setup do |
| 31 | + Application.put_env(:vbt, :ex_aws_client, VBT.TestAwsClient) |
| 32 | + mox().defmock(VBT.TestAwsClient, for: ExAws.Behaviour) |
| 33 | + :ok |
| 34 | + end |
| 35 | + |
| 36 | + @doc """ |
| 37 | + Stubs the `:request` function of the module returned by `VBT.Aws.client/0`. |
| 38 | +
|
| 39 | + The `response` argument can be either `t:VBT.Aws.response/0`, which represents the response |
| 40 | + of the operation, or a binary, in which case the response will be |
| 41 | + `{:ok, %{body: response, headers: [], status_code: 200}}`. |
| 42 | +
|
| 43 | + This function will also send a message in the shape of `{:aws_request, req, config}` to |
| 44 | + the caller process. Therefore, you can use `ExUnit.Assertions.assert_receive/3` to retrieve the |
| 45 | + request, and make further assertions. Note that this will only work if `assert_receive/3` is |
| 46 | + invoked in the same process as `stub_request/0`. Consequently, this approach will work if |
| 47 | + this function is invoked from `test`, or `setup` blocks, but not from `setup_all`. |
| 48 | +
|
| 49 | + This function is a lightweight wrapper around `Mox`. If you need more control, you can mock |
| 50 | + AWS client directly as follows: |
| 51 | +
|
| 52 | + Mox.stub(VBT.Aws.client(), :request, fn req, config -> ... end) |
| 53 | + """ |
| 54 | + @spec stub_request(VBT.Aws.response() | binary) :: :ok |
| 55 | + def stub_request(response) do |
| 56 | + test_pid = self() |
| 57 | + |
| 58 | + mox().stub(VBT.TestAwsClient, :request, fn req, config -> |
| 59 | + send(test_pid, {:aws_request, req, config}) |
| 60 | + |
| 61 | + case response do |
| 62 | + body when is_binary(body) -> {:ok, %{body: body, headers: [], status_code: 200}} |
| 63 | + {:ok, _} = success -> success |
| 64 | + {:error, _} = error -> error |
| 65 | + end |
| 66 | + end) |
| 67 | + |
| 68 | + :ok |
| 69 | + end |
| 70 | + |
| 71 | + defp mox, do: Mox |
33 | 72 | end |
| 73 | +else |
| 74 | + defmodule VBT.Aws.Test do |
| 75 | + @moduledoc """ |
| 76 | + Helpers for testing AWS interaction. |
34 | 77 |
|
35 | | - @doc """ |
36 | | - Stubs the `:request` function of the module returned by `VBT.Aws.client/0`. |
| 78 | + Note: Mox is not available in this environment. |
| 79 | + """ |
37 | 80 |
|
38 | | - The `response` argument can be either `t:VBT.Aws.response/0`, which represents the response |
39 | | - of the operation, or a binary, in which case the response will be |
40 | | - `{:ok, %{body: response, headers: [], status_code: 200}}`. |
41 | | -
|
42 | | - This function will also send a message in the shape of `{:aws_request, req, config}` to |
43 | | - the caller process. Therefore, you can use `ExUnit.Assertions.assert_receive/3` to retrieve the |
44 | | - request, and make further assertions. Note that this will only work if `assert_receive/3` is |
45 | | - invoked in the same process as `stub_request/0`. Consequently, this approach will work if |
46 | | - this function is invoked from `test`, or `setup` blocks, but not from `setup_all`. |
47 | | -
|
48 | | - This function is a lightweight wrapper around `Mox`. If you need more control, you can mock |
49 | | - AWS client directly as follows: |
50 | | -
|
51 | | - Mox.stub(VBT.Aws.client(), :request, fn req, config -> ... end) |
52 | | - """ |
53 | | - @spec stub_request(VBT.Aws.response() | binary) :: :ok |
54 | | - def stub_request(response) do |
55 | | - test_pid = self() |
56 | | - |
57 | | - mox().stub(VBT.TestAwsClient, :request, fn req, config -> |
58 | | - send(test_pid, {:aws_request, req, config}) |
59 | | - |
60 | | - case response do |
61 | | - body when is_binary(body) -> {:ok, %{body: body, headers: [], status_code: 200}} |
62 | | - {:ok, _} = success -> success |
63 | | - {:error, _} = error -> error |
64 | | - end |
65 | | - end) |
66 | | - |
67 | | - :ok |
68 | | - end |
69 | | - |
70 | | - defp mox do |
71 | | - # runtime checking the existence of mox to avoid compile-time warnings in dev/prod |
72 | | - unless Code.ensure_loaded?(Mox), |
73 | | - do: raise("mox library must be included in dependency") |
74 | | - |
75 | | - Mox |
| 81 | + def setup, do: raise("Mox is not available in #{Mix.env()} environment") |
| 82 | + def stub_request(_), do: raise("Mox is not available in #{Mix.env()} environment") |
76 | 83 | end |
77 | 84 | end |
0 commit comments