-
Notifications
You must be signed in to change notification settings - Fork 254
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
An unmocked method leaves its out parameter value untouched #590
Comments
@stakx @blairconrad Could you please describe the behavior of Moq and FakeItEasy in this regards? I could see value in both behaviors, so it would be interesting to see your conclusions ;-) |
@zvirja: Moq 4's behavior is as follows: When you don't set up the invoked method:Moq will behave in the same way as was described above for NSubstitute: The [Fact]
public void Moq_will_leave_out_arguments_untouched_if_invoked_method_not_set_up()
{
var foo = new Mock<IFoo>().Object;
int number1, number2;
number1 = 11;
number2 = 22;
foo.Baz(out number1);
foo.Bar(out number2);
Assert.Equal(11, number1);
Assert.Equal(22, number2);
} I tend to agree with OP that this could be considered a bug, since in C# methods must assign That being said, I'm not sure we'll change this behavior in Moq—it would be a breaking change, though admittedly not a very risky one, and noone's complained about it so far. The last is not surprising, since there's usually no point in manually initializing the variables that will be used as an argument to (P.S.: While Moq has other APIs and extensibility points like When you set up the invoked method:Moq will read the [Fact]
public void Moq_will_set_out_arguments_to_value_provided_in_out_parameter_at_setup_time()
{
var fooMock = new Mock<IFoo>();
int desiredNumber1 = 1111, desiredNumber2 = 2222;
fooMock.Setup(f => f.Baz(out desiredNumber1));
fooMock.Setup(f => f.Bar(out desiredNumber2));
var foo = fooMock.Object;
int number1, number2;
number1 = 11;
number2 = 22;
foo.Baz(out number1);
foo.Bar(out number2);
Assert.Equal(1111, number1);
Assert.Equal(2222, number2);
} Let me know if you'd like to know more. |
Hey, folks. FakeItEasy is no different—the value in the out argument will be left as it is. I don't mind this behaviour, to tell the truth. Sure, a hand-coded method with an out parameter must assign a value, but there's nothing that requires it to be equivalent to @davidnemeti, may I ask what unwanted behaviour occurred because of this? Did you have a test that failed (or passed when it shouldn't)? Can you give any details? If you have production code that is expecting the That being said, if a change were to be made, I very much like your suggestion of providing the same value as would be returned from an unconfigured method. /cc @thomaslevesque |
That's true in C#, because the compiler enforces it. But for the runtime, there's no difference between Sub Main
Dim x As Integer = 42
Test(x)
Console.WriteLine(x) ' Prints 42
End Sub
Sub Test(<Out> ByRef x As Integer)
End Sub Given that mocking libraries such as NSubstitute, Moq or FakeItEasy are not specific to C#, I'd say the current behavior is fine. |
@blairconrad, I just simply had a the test method in which I reused the variable which was an Then I called Something like this: var provider = Substitute.For<IFooProvider>();
provider.When(dtp => dtp.Do(out Arg.Any<int>())).Do(callInfo => callInfo[0] = 44);
int outValue;
provider.Do(out outValue);
// outValue is 44
callRouter = SubstitutionContext.Current.GetCallRouterFor(provider);
callRouter.Clear(ClearOptions.All);
provider.Do(out outValue);
// outValue is still 44 Now, I know that NSubstitute leaves the However, after reading @thomaslevesque's comment about VB.NET, I must say that this behavior should not be changed. |
Hi @stakx @blairconrad @thomaslevesque, Thank you very much for rich feedback you provided - that's very cool and helpful 😎 Take my apologize for the belated reply.
@stakx I've also found that it behaves like that even if you use argument specifier when configure a call ( I love the @thomaslevesque's argument about VB.NET and fact that our libraries are in fact multi-target. It sounds like a good excuse to continue behaving in a way we do 😉 Especially, given that NSubstitute officially provides analyzers for VB.NET, same as FakeItEasy. So I suggest to just keep things like they are, unless more people are concerned about this 😊 |
Describe the bug
An unmocked method leaves its
out
parameter value untouched, i.e. it does not set it to default value.Now, that seems a bit unorthodox, so I believe that it should set it to the default value. A normal (non-mocked) method cannot behave like this, i.e. it cannot leave its
out
parameter value as not set.Handling
out
parameters should be similar to handling the return value: an unmocked method returns the default value.To Reproduce
The above code produces the following output:
Expected behaviour
The above code should produce the following output:
Environment
The text was updated successfully, but these errors were encountered: