silverdr
There is the Recaptcha library
https://github.com/samueljseay/recaptcha
which helps me in verifying recaptcha responses. All nice. Time for testing (yeah, after getting code to work somehow – apologies to all TDD fans). Obviously I don’t want to hit uncle google with my tests, so:
Mox.defmock(MyApplication.Accounts.MockRecaptcha, for: MyApplication.Accounts.RecaptchaBehaviour)
inside test_helper.ex. Needed to define that behaviour separately:
defmodule MyApplication.Accounts.RecaptchaBehaviour do
@callback verify(String.t(), Keyword.t()) :: {:ok, Response.t()} | {:error, [atom]}
@callback verify(String.t()) :: {:ok, Response.t()} | {:error, [atom]}
end
do some tests using:
MyApplication.Accounts.MockRecaptcha
|> expect(:verify, fn _response -> {:ok, _response} end)
So far so good, except… all other tests are now failing with:
** (Mox.UnexpectedCallError) no expectation defined for MyApplication.Accounts.MockRecaptcha.verify/1 in process #PID<0.854.0> with args [nil]
Reading the fine docs I find: “[…] you might want the implementation to fall back to a stub (or actual) implementation when no expectations are defined. stub_with/2 is just what you need!”
So another line in test_helper.ex:
Mox.stub_with(MyApplication.Accounts.MockRecaptcha, Recaptcha)
That doesn’t work because ** (ArgumentError) Recaptcha does not implement any behaviour, Well.. let’s add my own “proxy” then, which does:
defmodule MyApplication.Accounts.Recaptcha do
@behaviour MyApplication.Accounts.RecaptchaBehaviour
def verify(response, options \\ []) do
Recaptcha.verify(response, options)
end
end
And change the test_helper.ex line to
Mox.stub_with(MyApplication.Accounts.MockRecaptcha, MyApplication.Accounts.Recaptcha)
Now the ArgumentError is gone but all tests with no Mox expectations fail the same as before. No change with and without the stub_with/2.
And I feel like I spent already far too much time with it…
Any help to put me on track?
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixirconf-us
- #ai
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming











Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
silverdr
Since nobody seems to be able to step-in I added a
TL;DR
Unrelated tests fail because “no expectation defined” when using Mox library and
stub_with/2doesn’t seem to be of any helpand posted this question on SO:
travisf
I am by no means an expert on mocks, but recently I have implemented a few. I found this article super helpful. Specifically he talks about using environments to replace the module, in your case, ReCapthca, in the tests.
So in the modules where the recaptcha is called you would replace
Recaptcha.verify(response, options)with:Then in your
test_helper.exsunder the mock definition you can add:Application.put_env(:my_app, :recaptcha, MyApplication.Accounts.MockRecaptcha).Remember to add:
config :my_app, :recaptcha, MyApplication.Accounts.Recaptchato yourconfig.exsso the Recaptcha works in all other environments.That should enable the Mox
expect/2to work in the test.I’m not sure about the
Mox.stub_with/2function in the test_helper, I haven’t played with Mox stubs.ruslandoga
I have a telegram bot client in my app which uses both mocks and stubs during tests and it seems to work fine. Here’s it’s setup:
config/test.exslib/bot.exlib/bot/adapter.extest/support/mocks.exstest/support/stub_bot.exand finally
test/support/data_case.exand other helper cases for tests that end up touching the bot module haveMox.stub_with/2insetup:silverdr
Thank you for sharing. Do you have anything else (like tests in other files) hitting the code of your
@App.Bot.Adapter? Or – IOW – if you remove thestub_withdo you get the same error(s) as I do (about “no expectation defined”) from other test files?ruslandoga
Yes, the bot logs “important” messages, so the stub is executed somewhat often in tests.
silverdr
expect/2works as.. well.. expected. The problem is with unrelated tests that now fail because of “no expectation defined”, for which thestub_with/2is supposed to be a curesilverdr
And – just to make sure – you didn’t have to adapt/modify any of the other test files, did you?
ruslandoga
Are asking if I had to add
Mox.expecteverywhere?silverdr
Or anything for that matter, that would make them work normally.
Yet I was writing this at the same time while you were checking whether removing the
stub_with/2fromtest_halper.exmakes any difference. And if I add thestub_with/2to e.g.conn_case.exthen test files, whichuse MyApplication.ConnCasepass (!). And I guess that if you left the line intest_helper.exand removed it fromdata_case.exyou’d encounter the same issue I have. If that’s the case then - WTH? Test files “see” thedefmockbut don’t “see” thestub_withdefined in the very same (test_helper.ex) file?silverdr
Right - if I put the
stub_withinto bothconn_caseanddata_casethen all tests work normally. IOW – @ruslandoga – you’re my saviour, man! I guess it has to be invoked always in the given test file context. If I now re-read the doc, the wording might actually imply this… gosh!