Skip to content

Detect Thrown Exceptions From Mocks #377

Closed
@JasonBock

Description

@JasonBock

Describe the solution you'd like
If a mock throws an exception, we should track that on the expectations and use that knowledge to not throw an exception in Verify(). The reason why is because of RockContext. Let's say we did something like this:

public interface IThing
{
  void DoStuff();
  void DoOtherStuff();
}

using var context = new RockContext();
var expectations = context.Create<IThing>();
expectations.Methods.DoOtherStuff();

var mock = expectations.Instance();
mock.DoStuff();

We have an expectation set for DoOtherStuff(), but we call DoStuff(). That throws an ExpectationException, but what happens is in the finally block, Verify() is called and that will throw a VerificationException stating that DoOtherStuff() was never invoked. Which is true, but this is masking the exception thrown from the mock's DoStuff() implementation. We don't want to do that, as it may be confusing to the user.

I think the way to handle this is to generate a private bool WasExceptionThrown { get; set; } on the generated expectations type, and when the mock implementation is going to throw an exception, it sets this flag. Then, in Verify(), we only do verification if WasInstanceInvoked is true and WasExceptionThrown is false.

If a user defines a callback that throws an exception, we can't do anything about that. We're assuming the user is doing that on purpose and will check for that exception in their code as an expected behavior.

Sadly, this adds more code to a mock member's implementation, so performance numbers will go up a bit (sad!). But it'll be a very small perf hit, and it's necessary for correctness.

Describe alternatives you've considered
Keep things the way they are, but that's kind of bad.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions