Mox strange race conditions

I seem to be getting some strange undefined behavior when defining multiple separated mocks for the same module in the same test:

  HttpClientMock
  |> expect(:request, fn request -> build_response() end)
  |> allow(self(), fn -> Process.whereis(MyProcess) end)

# Later in that same test

  HttpClientMock
  |> expect(:request, fn request -> build_another_response() end)
  |> allow(self(), fn -> Process.whereis(MyNewProcess) end)

Is this a limitation that Mox has? I’ve read already the documentation a few times and I couldn’t find any things specified about this, it is completely unclear what happens under the hood as it seems these definitions are doing only side-effects.

I skimmed through the docs and the code and I suspect you’re encountering a bug. The new expectations are probably not merged correctly with the existing ones.

This is extremely strange because this is not consistent, even though my calls in tests are always deterministic. Sometimes the test can fail on the second expectation and sometimes on the first one.

Maybe you can use a helperAgent to register which expectation is called when and determine if there’s any logic to the behaviour you’re observing.

Nevermind, looks like I had a race condition in my processes :sob: .

What kind of? Could be useful for future readers.

Note for the future readers: there was a bug with multiple lazy defined allowances until v1.2.0 which I fixed.

2 Likes

I am not sure how I can show an example, what I have are multiple genservers (some of them dependent on each-other) hitting multiple HTTP APIs.

I can confirm that with version 1.1.0, even with the race condition fixed in my application code, the tests still fail randomly as before, I’ve actually upgraded the dependency right in the middle of writing this topic so I might have experienced that bug too before upgrading. I did not mention it, because I didn’t saw bugfixes mentioned in changelogs of the new version. Thanks for the fix!

2 Likes

Well, technically I brought this bug and then I fixed it.

The deferred allowance is my idea and my implementation, probably that is why it was buggy in the first place :slight_smile:

1 Like