C
C#13mo ago
joren

❔ ✅ Verifying the purpose of Moq usage

mockDatabase.Setup(db => db.GetUserName(It.IsAny<int>()))
.Returns((int userId) => "User" + userId);
mockDatabase.Setup(db => db.GetUserName(It.IsAny<int>()))
.Returns((int userId) => "User" + userId);
So, as you can see I use It.IsAny<int>() to mimic a value that would be passed, since GetUserName() requres an integer passed as argument. However this value is not used in the actual mock, but rather the
string result = userManager.GetUserDisplayName(42);
string result = userManager.GetUserDisplayName(42);
the 42 that is passed here, which then calls GetUserName() inside of it.
35 Replies
joren
jorenOP13mo ago
Now this makes sense to me, but I just need to be sure that the purpose of It.IsAny<int>() here is to comply with the fact that GetUserName() requires one argument, and therefore just writing it without any value would not compile.
// Assert
Assert.Equal("User42", result);
// Assert
Assert.Equal("User42", result);
Is what it Assert's on, which is the 42, not the random value or the default(T) I think It.IsAny<int>() would return.
Pobiega
Pobiega13mo ago
not the random value or the default(T) I think It.IsAny<int>() would return.
thats not at all what It.IsAny does it doesnt actually make a value, its telling Moq that "regardless of what int is passed in" it just has to be an int
joren
jorenOP13mo ago
more like a constraint then?
Pobiega
Pobiega13mo ago
you could do
mockDatabase.Setup(db => db.GetUserName(42))
.Returns((int userId) => "User" + userId);
mockDatabase.Setup(db => db.GetUserName(42))
.Returns((int userId) => "User" + userId);
if this setup should only trigger on that value
joren
jorenOP13mo ago
Ahh, so only when called with 42 it will work
Pobiega
Pobiega13mo ago
yeah
joren
jorenOP13mo ago
string result = userManager.GetUserDisplayName(42); would work, but if I change it to 32 it will throw an exception?
Pobiega
Pobiega13mo ago
this might be useful if you have a test where the thing you test calls the same dependant method twice but with different expected return values
joren
jorenOP13mo ago
so you basically ensure that the value used is the same otherwise the test is obviously rendered useless Makes sense, what if the condition of 42 (in this example) isnt met? Exception I assume, or
Pobiega
Pobiega13mo ago
default iirc so 0 for an int you can however use moqs verification tools to make sure only some calls were made
joren
jorenOP13mo ago
I see, I dont think I need to get that deep yet. My work is slowly implementing Moq, so I guess I'll learn about it when I need to use something like that fancy though
joren
jorenOP13mo ago
No description
Pobiega
Pobiega13mo ago
default for a string is null
joren
jorenOP13mo ago
so if the condition isnt met, it returns null
Pobiega
Pobiega13mo ago
so yeah? btw, a lot of people are moving away from Moq currently
joren
jorenOP13mo ago
Oh, really? I was under the impression that this is the thing to use same with Xunit
joren
jorenOP13mo ago
oh boy thats not a small accusation actually
Pobiega
Pobiega13mo ago
tldr: the author added a weird obfuscated dll that he was also the author of, that slowed down CI builds and dumped messages in the logs about donating to projects, and it gathered git author emails while doing so
joren
jorenOP13mo ago
SponsorLink DLLs contain obfuscated code
Pobiega
Pobiega13mo ago
people were rightly pissed as hell he did revert the changes after a few days, but its clear he still believes he did nothing wrong
joren
jorenOP13mo ago
he obfuscated it too, thats tricky
Pobiega
Pobiega13mo ago
so a lot of people just lost trust in him
joren
jorenOP13mo ago
Yeah, makes sense. Dangers of updating your packages without looking at its changes I suppose kind of sad that we have to be careful with things like that
Pobiega
Pobiega13mo ago
it is indeed. anyways, a lot of people are thus moving away from Moq and using NSubstitute instead its similar in terms of features, just has a different syntax you can ofc keep using Moq, just thought you should know
joren
jorenOP13mo ago
Alright, thanks for the heads up. I will discuss this with my teamleader, see whats up As for the It.Any<int>(), in the case of my example. Would you consider doing:
mockDatabase.Setup(db => db.GetUserName(42))
.Returns((int userId) => "User" + userId);
mockDatabase.Setup(db => db.GetUserName(42))
.Returns((int userId) => "User" + userId);
better practice than It.Any<>?
Pobiega
Pobiega13mo ago
nah when it comes to mocking, just keep it simple and readable in that case, it doesnt matter but I'd be wary of hardcoding stuff like the 42 regardless, even in the assert id rather use constants so if you have to change it for some reason, its changed everywhere
joren
jorenOP13mo ago
yes I'd write it like this:
constexpr int kUserIDMock = 42;

// use in both
constexpr int kUserIDMock = 42;

// use in both
speaking of
Pobiega
Pobiega13mo ago
sure
joren
jorenOP13mo ago
how do u declare a constant in C# const, final?
Pobiega
Pobiega13mo ago
const int userId
joren
jorenOP13mo ago
is that a runtime constant or a compile time one
Pobiega
Pobiega13mo ago
no compile time
joren
jorenOP13mo ago
Alright, sweet nice Thanks, I'll stop bothering you now :) /close
Accord
Accord13mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server