-
-
Notifications
You must be signed in to change notification settings - Fork 812
Allow specifying action if setup was not met in strict mode #856
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
Comments
I don't think it would be a good idea to make strict mocks' by-default throwing behavior configurable, because that would make the meaning of "strict mock" less clear. Having a strict mock means that you need to provide the behavior (i.e. as setups) for each and every expected call. As soon as you introduce some kind of user-defined default behavior, this rule no longer holds and "strict" becomes a little less meaningful. Therefore, perhaps the right place for a fallback behavior is not at the level of the mock, but of an individual setup.
There's a problem with the if-else syntax you propose. Either this setup is matched, and it gets executed, or it isn't matched, and its "else" part gets executed. So what if there are other setups that would match? Should the "else" part still be executed, or should another, better-matching setup be preferred over this one? We don't need to find an answer to these questions because Moq already gives you the means to specify a fallback. Later setups generally "win" over earlier ones, so you can do this: mock.Setup(m => m.Action(It.IsAny<string>()).Throws(new NotFoundException());
mock.Setup(m => m.Action(It.IsIn(idsList)).Returns((string s) => objectList.First(o => o.Id == s)); (Or, if you don't want two setups, combine them into one:) mock.Setup(m => m.GetById(It.IsAny<string>()))
.Returns((string id) => objectList.FirstOrDefault(o => o.Id == id) ?? throw new NotFoundException()); No special if-else setup API required. And, if you do that repeatedly and want to stay DRY, you can create a helper method for this setup pattern. IIRC, the upcoming Moq v5 might allow you to configure the default mock behavior more flexibly than is possible in v4. |
Good answer. My intention was to not have any "logic" in mocks but a null check should be fine. It's a good hint that default behavior independent of values can be set up like that. Indeed, defining the negative case first is a shorter and more readable after one gets used to the idea. Thanks for the reply. |
Let's say I try to set up a Mock to behave like a database. For this, I have a simple list with three strings representing identifiers. Then I have following setup:
There are many methods that operate on identifiers. As in a real world scenario, supplying an ID that does not exist leads to some (hopefully) predictable error. I dislike my setup because:
Even though one could get around the verbose setup with some additional C# code by extending Linq, it is not possible to do so to avoid the MockException. Switching to loose mode is not an option because strict mode is great.
But for the scenario described above it would be nice to be able to do something like this:
This would allow to act powerful on these conditions. Since I don't every method to behave like this, the "normal" setup should rather stay as it is.
Since one will mostly throw specialized Exceptions in these cases, syntax sugar would be also appreciated, i.e.:
I found this piece of code that is responsible for the current behavior:
Could this somehow be modified to pick up a provided error as described above?
The text was updated successfully, but these errors were encountered: