Comments (6)
You have two invocations, so your predicate runs twice (once per invocation) per
Verify
call. Am I still misunderstanding?
Verify
cannot magically know which invocations will match the predicate and which ones won't. It uses the predicate to determine that, which is why the predicate runs once per invocation.
Okay that now makes total sense... The issue is indeed with the Assert throwing.
Since we indeed have to go through all the invocations to validate the predicate, once we execute the validation with the wrong input the Assert will throw.
Thank you very much for the quick help and responses, and for clarifying the case here!
from moq4.
Hi @AntonVasserman. I haven't run your code, but by just looking at it, I suspect the problem doesn't lie with Moq, but with your usage of Assert.Equal
inside ValidateModel
. Assert.Equal
may throw exceptions. The predicate function passed to It.Is<>
OTOH should never to throw, but simply return a bool
indicating whether a positive match was made or not. That is, your ValidateModel
method should convert thrown exceptions to a return value of false
(or even more simply, just use object.Equals
instead of Assert.Equal
); then the rest of your code should work as expected.
(Also, if it isn't self-evident: mock.Verify
has to run the predicate against all invocations to figure out how many of them match the predicate; that is, you should expect that your predicate gets run against invocations that may not match it. That's why the use of a possibly-throwing Assert.Equal
inside the predicate is an error.)
from moq4.
@stakx No I don't think this is related.
The only reason ValidateModel
throws is because there is a second execution of the It.Is<>
for some reason.
I have changed the code to this:
public class Program
{
private static int _count = 0;
public static void Main(string[] args)
{
Mock<ISomeInterface> mock = new();
SomeClass someClass = new(mock.Object);
SomeModel someModel1 = new() { Value = 1 };
SomeModel someModel2 = new() { Value = 2 };
List<SomeModel> list = new List<SomeModel> { someModel1, someModel2 };
someClass.BatchedMethod(list);
// This first call actually verifies both invocations
mock.Verify(m => m.SomeMethod(It.Is<SomeModel>(actualModel => ValidateModel(actualModel, someModel1))), Times.Exactly(2));
// This second call is never even called since the first one fails on its second run due to 'actualModel' being 'someModel2'...
// mock.Verify(m => m.SomeMethod(It.Is<SomeModel>(actualModel => ValidateModel(actualModel, someModel2))), Times.Once());
Console.WriteLine($"Finished: {_count}");
}
private static bool ValidateModel(SomeModel actualModel, SomeModel originalModel)
{
// Assert.Equal(actualModel.Value, originalModel.Value);
if (originalModel.Value == 1) _count++;
return true;
}
}
And this is the value I get:
This is even though we, supposedly, call mock.Verify(m => m.SomeMethod(It.Is<SomeModel>(actualModel => ValidateModel(actualModel, someModel1))), Times.Exactly(2));
once, so it clearly means that the method is called twice for some reason.
(Note I had to change Times.Once
to Times.Exactly(2)
so it won't throw...)
from moq4.
You have two invocations, so your predicate runs twice (once per invocation) per Verify
call. Am I still misunderstanding?
Verify
cannot magically know which invocations will match the predicate and which ones won't. It uses the predicate to determine that, which is why the predicate runs once per invocation.
from moq4.
Note I had to change
Times.Once
toTimes.Exactly(2)
so it won't throw...
This doesn't match with your code comments in the example shown:
// This first call actually verifies both invocations mock.Verify(m => m.SomeMethod(It.Is<SomeModel>(actualModel => ValidateModel(actualModel, someModel1))), Times.Exactly(2)); // This second call is never even called since the first one fails on its second run due to 'actualModel' being 'someModel2'... // mock.Verify(m => m.SomeMethod(It.Is<SomeModel>(actualModel => ValidateModel(actualModel, someModel2))), Times.Once());
from moq4.
You're welcome. Glad I could help with clearing things up.
from moq4.
Related Issues (20)
- invalid path on linux HOT 1
- Verify something for each item in a list HOT 2
- Running unit tests through Rider causes AD0001 : Analyzer 'Moq.SponsorLinker' threw an exception of type 'System.UnauthorizedAccessException' HOT 2
- Warnings with latest version from SponsorLink HOT 33
- Upgrading to version 4.20.1 breaks the build HOT 6
- Privacy issues with SponsorLink, starting from version 4.20 HOT 393
- SponsorLink and supporting OSS more broadly HOT 727
- Strange System.UnauthorizedAccessException during build using latest version HOT 4
- SponsorLink is now OSS too and no longer bundled HOT 87
- Trouble to unit test a lambda expression with Moq HOT 1
- Default value ILookup<> in loose mode is `null` HOT 2
- Permanently delete all data from SponsorLink's database that has been collected during builds that included Moq (notably any version 4.20.*) HOT 18
- Stop using Moq as a guinea pig to get feedback on and develop SponsorLink HOT 105
- Support Static Abstract property HOT 1
- Community Involvement HOT 5
- Change log is not updated since version 4.18.4 HOT 3
- Mocking Blobclient.DownloadContentAsync() HOT 3
- Poll on SponsorLink HOT 1
- Should allow null references as constructor parameters. HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from moq4.