Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When testing a method which overrides a method in the base class, the unit test always passes. #1180

Closed
Jakob-Eichberger opened this issue Jun 30, 2021 · 3 comments

Comments

@Jakob-Eichberger
Copy link

Jakob-Eichberger commented Jun 30, 2021

When I'm trying to mock a class that derives from another (none virtual) class the unit test always passes.
Lets look at an example where I think the bug can be seen clearly:
• We have two classes. Class B which has a virtual method (with the name AMethod() and ...
• Class A, which derives from B and overrides its virtual method.

• Both methods (so the virtual class in B and the method in A) throw an exception.
image

When we now create a unit test that tests the method AMethod in A, the test should fail, since AMethod throws an exception.
image
But as you can see the test passes:
image

Now I think this might be a bug, because when I convert B to an interface the method failes as expected.
image
As you can see the unit test for the method AMethod in the class A fails.
image

One more thing to note is that when B was a class and not an interface, setting a breakpoint in the methods in A or B did not work, so I'm assuming the method in A nor B are never actually called?

@Jakob-Eichberger
Copy link
Author

Closed.
I found a "fix" for the problem. The property CallBase needs to be set to true to avoid this behavior. :)

But one thing I'm wondering is, why does this property exist? And more importantly why does the unit test not fail?

@stakx
Copy link
Contributor

stakx commented Jun 30, 2021

why does the unit test not fail?

Moq by default intercepts / stubs all methods that it can (that is, all overridable ones), which is why your original implementation gets overridden with one that doesn't really do anything (unless you set it up). So your throw no longer executes.

why does this property (CallBase) exist?

Because sometimes you don't want a full stub, but you may want to defer to the implementation from the mocked type (which yields a so-called "partial mock"). You can choose that as the default for all methods using mock.CallBase = true, or for single methods using mock.Setup(m => m.Method(...)).CallBase().

when I convert B to an interface the method failes as expected

Not only did you convert B to an interface, you also made A.AMethod non-virtual, so Moq cannot intercept it, which is why the original implementation will get called.

@Jakob-Eichberger
Copy link
Author

Thank you for the detailed answer!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants