-
Notifications
You must be signed in to change notification settings - Fork 260
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
Allow setting of out parameters #488
Comments
Thanks for the suggestion! I wonder if this would be possible to do by modifying // Proposed:
lookup.TryLookup("hello", out Arg.Do(ref string x => x = "world"))
.Returns(true); I haven't had a chance to look much into @zvirja: Any ideas about this? |
Hi David, My initial thought was also to re-use the existing However, after giving it more precise look, I found myself to be reluctant to add this feature. The main concern is that lookup.TryLookup("hello", ref Arg.Set(42)).Returns(true, false); How should we expect Other sample: lookup.TryLookup("hello", ref Arg.Set(42))
.Returns(x => true, x => { x[1] = 44; return true; }, x => false) Should Probably, if we look even more, we could see other scenarios where feature isn't that obvious. Given that Instead, we might solve this by analyzers from @tpodolak, so they catch when we assign value incorrectly (if we don't do that already...). |
Thanks for the comments guys, much appreciated. With regards to using lookup.TryLookup("hello", out Arg.Do((ref string x) => x = "world"))
.Returns(true); The points about The main improvement I see for the feature was working with Happy to close the request if you think it doesn't add any merit, however, equally as happy to do the work to implement the specification you come up with 🙂 |
I would vote for do nothing for now. While I don't like the current syntax with the array of objects, I don't see a nice and consistent way to set and check refs/outs. (Maybe the FakeItEasy approach is a bit nicer, see below). @zvirja already mentioned a few edge cases and there are more (ref/out can be used in arg matchers, multiple return specs, partial mocks) I reviewed what other frameworks have for ref/out. Moq has
FakeItEasy has a dedicated method to set refs and outs (looks neat for me):
It seems that Typemock and JustMock just pass argument values. I believe they should have "callback" feature but unfortunately I couldn't find any example in docs. |
Thanks for all the good points everyone!
I've been doing some non-.NET work for a while now, so I'm not sure about this, but from recent C# changes like the ref-returns stuff I wonder if these are going to become more commonplace?
It definitely has merit @samcragg! It's just whether we can get it to slot in with other features. Thanks for raising it, and your generous offer to help implement! 😄
Looks neat to me too! We can already do something similar with sub.Lookup("blah", out Arg.Any<int>())
.Returns(true)
.AndDoes(x => x[1] = 45); We could possibly have another dedicated method on While trying out this example, I realised we already have the problem Alex mentioned with synchronising with public interface ILookup { bool Lookup(string key, out int i); }
[Fact]
public void Test() {
var sub = Substitute.For<ILookup>();
sub.Lookup("blah", out Arg.Any<int>())
.Returns(x => {
x[1] = 42;
return true;
})
.AndDoes(x => x[1] = 45);
sub.Lookup("blah", out var value);
Assert.Equal(??, value);
} In this test, I'm pretty torn about this. The edge cases raised are very valid and good illustrations of the confusion this can cause; but on the other hand the So I guess I'm on the fence on this one (as usual 😂). Happy to accept your "hold" votes on this @alexandrnikitin and @zvirja until we get more demand for the feature. Or if my rambling here has changed your minds I'd also be happy to get this added to main |
I'm loving the work done under #401 to make the syntax for
ref
/out
parameters much better, i.e. we can now say:However, the syntax to set the argument is still a bit clunky:
I was wondering if you would be happy for me to submit a PR to take it one step further and let you change the argument, so I'm thinking of something like this:
Arg.Set
(happy for you to pick another name 🙂) would have the same match semantics asArg.Any
- if you wanted the ability to selectively set the argument I guess we could have anArg.SetWhen(condition, value)
method perhaps, though personally I've never had a need to do argument matching onout
parameters as you have to set them in the method anyway plus if the user did want this they could switch back to the more verbose syntax.Thoughts?
The text was updated successfully, but these errors were encountered: