Skip to content
This repository was archived by the owner on Nov 30, 2024. It is now read-only.
This repository was archived by the owner on Nov 30, 2024. It is now read-only.

An unexpected args error confuses minitest when it looks for the source line #1592

Closed as not planned
@onlynone

Description

@onlynone

Subject of the issue

We're using rspec-expectations, rspec-mocks with minitest. We're using the minitest_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:

class ExampleTest
  test "something" do
    expect(a_real_object).to receive(:a_method).with("these", "args")
    do_something
  end
end

And if do_something eventually results in a call to a_real_object.a_method, but with different arguments. We'll get failure output like:

Failure:
ExampleTest#test_something [/Users/user/.gem/ruby/2.7.8/gems/rspec-mocks-3.12.5/lib/rspec/mocks/proxy.rb:217]:

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:

"/Users/user/.gem/ruby/2.7.8/gems/rspec-support-3.12.0/lib/rspec/support.rb:102:in `block in <module:Support>'",
"/Users/user/.gem/ruby/2.7.8/gems/rspec-support-3.12.0/lib/rspec/support.rb:111:in `notify_failure'",
"/Users/user/.gem/ruby/2.7.8/gems/rspec-mocks-3.12.5/lib/rspec/mocks/error_generator.rb:348:in `notify'",
"/Users/user/.gem/ruby/2.7.8/gems/rspec-mocks-3.12.5/lib/rspec/mocks/error_generator.rb:332:in `__raise'",
"/Users/user/.gem/ruby/2.7.8/gems/rspec-mocks-3.12.5/lib/rspec/mocks/error_generator.rb:55:in `raise_unexpected_message_args_error'",
"/Users/user/.gem/ruby/2.7.8/gems/rspec-mocks-3.12.5/lib/rspec/mocks/message_expectation.rb:555:in `raise_unexpected_message_args_error'",
"/Users/user/.gem/ruby/2.7.8/gems/rspec-mocks-3.12.5/lib/rspec/mocks/proxy.rb:217:in `message_received'",
"/Users/user/.gem/ruby/2.7.8/gems/rspec-mocks-3.12.5/lib/rspec/mocks/proxy.rb:361:in `message_received'",
"/Users/user/.gem/ruby/2.7.8/gems/rspec-mocks-3.12.5/lib/rspec/mocks/method_double.rb:91:in `proxy_method_invoked'",
"/Users/user/.gem/ruby/2.7.8/gems/rspec-mocks-3.12.5/lib/rspec/mocks/method_double.rb:67:in `block (2 levels) in define_proxy_method'",
"/Users/user/project/lib/example.rb:10:in `do_something'",
"/Users/user/project/test/unit/lib/example_test.rb:4:in `block in <class:ExampleTest>'",
"/Users/user/.gem/ruby/2.7.8/gems/minitest-5.11.3/lib/minitest/test.rb:98:in `block (3 levels) in run'",
"/Users/user/.gem/ruby/2.7.8/gems/minitest-5.11.3/lib/minitest/test.rb:195:in `capture_exceptions'"

So this line gets matched by the regex:

"/Users/user/.gem/ruby/2.7.8/gems/rspec-mocks-3.12.5/lib/rspec/mocks/message_expectation.rb:555:in `raise_unexpected_message_args_error'",

And then this line is the next one, where minitest thinks the error is:

"/Users/user/.gem/ruby/2.7.8/gems/rspec-mocks-3.12.5/lib/rspec/mocks/proxy.rb:217:in `message_received'",

I feel like it would be more correct for the location of the error to be:

"/Users/user/project/lib/example.rb:10:in `do_something'",

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 by rspec-mocks as a RSpec::Mocks::MockExpectationError. I'm guessing it's the minitest_integration that sets that class to Minitest::Assertion.

Your environment

  • Ruby version: 2.7.8
  • rspec-mocks version: 3.12.5
  • rspec-expectations version: 3.12.2
  • rspec version: 3.12.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions