rollbear / trompeloeil

Header only C++14 mocking framework
Boost Software License 1.0
802 stars 85 forks source link

unreal engine support & noreturn/std::abort #327

Open akhosravian opened 9 months ago

akhosravian commented 9 months ago

Hi!

I'm trying to use trompeloeil with Unreal Engine. I was able to get it up and running using the steps in the manual to create either a compile or run time adapter; however, Unreal's tests run inside a longer lived process and that means trompeloeil's out of the box behavior for invalid mock calls (aborting the test process) is inappropriate.

I sidestepped this using a custom #define before including trompeloeil.hpp that does a few things:

  1. define TROMPELOEIL_NORETURN to nothing
  2. removed the call to std::abort in report_mismatch
  3. return at the end of the if(!i) block in mock_func.

There are other spots where std::abort appears, but this was enough to get basic failures playing well with Unreal's tests. Any obvious land mines with this approach? Is this something you'd be interested in seeing a PR for?

rollbear commented 9 months ago

Yes, there are land mines here.

What if a violation occurs in a function that returns something that the framework cannot create? There simply is no way to continue.

akhosravian commented 9 months ago

Yep that's true. A lot of Unreal uses return types that are default or trivial constructible (favoring out parameters by reference for spots that may be a bad idea) so I didn't run into that with my initial exploration. Do you have any suggestions on approaches for getting suitable beahvior in place there? I'd guess I could get a lot of mileage out of trompeloeil even with compile time errors (only) for bad mocks, but I might be able to set up some kind of run time adapter for aborting the current test.

I'm open to doing a lot of the lifting for this myself (i.e. porting the tests to unreal and working through issues there), but would appreciate if you think it'd be a waste of time 😄

rollbear commented 9 months ago

I admit that I haven't thought very much about this, because I think that when a test fails, you really don't want to continue running because nothing valuable will come out of it. Abort/terminate/crash is unfortunate, but it only happens when a bug has been caught, which really ought to be very rare, so it's not a big deal. I strongly dislike the idea of a solution that only works in some circumstances.

I've been toying with the idea of a co-routine based testing framework that'd co_return a violation, which maybe could work, but it's nothing more than a vague idea at this point and won't address your current needs.