-
-
Notifications
You must be signed in to change notification settings - Fork 358
An unexpected args error confuses minitest when it looks for the source line #1592
Comments
👋 This is up to minitest, we use Ruby semantics when it comes to raises errors or allowing errors to be raised. In |
For that to work, wouldn't minitest need to have detailed backtrace filtering heuristics for any third-party testing tool that might raise errors from deep within their own code? Minitest already does its own filtering of backtraces to weed out its own code, but after that it just looks to where the raise happened. It seems like it could be pretty helpful if rspec could craft a backtrace that pointed to where the mock actually received the bad call. |
Gem names create predictable filenames, in |
We may be misunderstanding each other. I think the problem is that rspec isn't the one displaying the backtraces, minitest is. That library looks through the backtrace to see if they can find where something was raised or asserted. To that library, there's no difference between an exception being raised in rspec's code (or any other random assertion/expectation library) and user code. However, when rspec creates the exception, it could pre-remove its own lines from the exception's backtrace so that the first line would point to where the problem happened in the user's code. I created a PR to show what I mean in #1593 . |
We just solve this problem with a feature to filter gems out which are considered 3rd party, it could be rspec-mocks, or shoulda, or any other library. Minitest could also implement a feature like this. Removing the backtrace lines would duplicate our logic for filtering out lines when displaying them, and also circumvent our feature which allows you to optionally remove that filtering and see the entire stacktrace, so changing this behavious is not something we want to do. |
Is there a way to leverage the existing code in rspec-core to do this then? I feel like there's not a lot of duplication since the issue I'm having isn't about filtering out arbitrary third-party gems. It's just having rspec-mocks remove its own lines from backtraces. Since rspec-mocks is where the exception is created, it seems like it would be the best and most direct place to deal with removing the extra lines.
That sounds like an essential feature, I think it would make sense to make the type of filtering I'd like configurable as well. Is there some way you could see that rspec-mocks could leverage all the existing code and configuration from rspec-core to do this. Or could the feature I'd like to see added to rspec-mocks be placed behind its own option? |
I'm viewing this similar to how mock expectations that don't fire a failure until teardown will set the |
Subject of the issue
We're using
rspec-expectations
,rspec-mocks
withminitest
. We're using theminitest_integration
with both of them. For the most part everything works well. But sometimes failures cause minitest's location logic to not find where the problem really occurred.For example, we have a test like:
And if
do_something
eventually results in a call toa_real_object.a_method
, but with different arguments. We'll get failure output like:But that source location isn't very helpful. I traced it down to the way minitest looks for a probable failure line. It looks at the backtrace of the exception and grabs the line just after a line matching the regex
/in .(assert|refute|flunk|pass|fail|raise|must|wont)/
(note, this is based on the version of minitest I'm using, but the most recent version does essentially the same thing).And the backtrace looks like:
So this line gets matched by the regex:
And then this line is the next one, where minitest thinks the error is:
I feel like it would be more correct for the location of the error to be:
Is there some way
rspec-mocks
could create an exception with a backtrace that leads to the project's code rather than itself?FYI: The actual exception being raised is a
Minitest::Assertion
, but it was created byrspec-mocks
as aRSpec::Mocks::MockExpectationError
. I'm guessing it's theminitest_integration
that sets that class toMinitest::Assertion
.Your environment
The text was updated successfully, but these errors were encountered: