Out Parameters

396 views
Skip to first unread message

doyouun...@gmail.com

unread,
Sep 11, 2008, 7:35:18 PM9/11/08
to Moq Discussions
Is there any plan to implement out parameters in the future?

I realize they're usually to be avoided, but every once in a while
they make sense (Like with TryParse patterns).

Currently, I'm just unable to test these types of service calls using
Moq.

Daniel Cazzulino

unread,
Sep 12, 2008, 5:25:04 PM9/12/08
to moq...@googlegroups.com, Moq Discussions
TryParse is typically static, so I hope you're not asking for that
too ;)

Sent from my iPod

Emad Ibrahim

unread,
Sep 14, 2008, 1:48:53 PM9/14/08
to Moq Discussions
Another vote for out parmaeters.

The Membership.CreateUser method has an out paramater and it is
impossible to mock... Any suggestions?

On Sep 12, 5:25 pm, Daniel Cazzulino <dan...@cazzulino.com> wrote:
> TryParse is typically static, so I hope you're not asking for that  
> too ;)
>
> Sent from my iPod
>

Daniel Cazzulino

unread,
Sep 14, 2008, 3:49:18 PM9/14/08
to moq...@googlegroups.com, Moq Discussions
You mean other than "it would be great if you could submit a patch" ? ;)

Sent from my iPod

Daniel Cazzulino

unread,
Sep 28, 2008, 7:16:58 PM9/28/08
to moq...@googlegroups.com
Out/Ref parameters are now in the trunk :))))

Emad Ibrahim

unread,
Sep 29, 2008, 9:41:33 AM9/29/08
to Moq Discussions
That is freaking awesome... how about a little example? :)

On Sep 28, 7:16 pm, "Daniel Cazzulino" <dan...@cazzulino.com> wrote:
> Out/Ref parameters are now in the trunk :))))
>
> On Sun, Sep 14, 2008 at 4:49 PM, Daniel Cazzulino <dan...@cazzulino.com>wrote:
>
> > You mean other than "it would be great if you could submit a patch" ? ;)
>
> > Sent from my iPod
>

Daniel Cazzulino

unread,
Sep 29, 2008, 1:16:29 PM9/29/08
to moq...@googlegroups.com

Daniel Cazzulino

unread,
Sep 29, 2008, 1:18:24 PM9/29/08
to moq...@googlegroups.com
the coolest thing (IMO) is that whichever the value of the variable you pass as out/ref, that's the value that will be returned/set when the method is invoked :D

TrueWill

unread,
Oct 4, 2008, 11:53:51 PM10/4/08
to Moq Discussions
Thank you very much! I agree with the other posters - the key use of
out parameters is in the TryParse pattern, as specified in the book
Framework Design Guidelines and at http://msdn.microsoft.com/en-us/library/ms229009.aspx
- and these methods are not always static. For example, our company's
object persistence layer has non-static TryLoadById methods.

TrueWill

unread,
Oct 8, 2008, 12:45:13 PM10/8/08
to Moq Discussions
Thanks much for releasing the new version with out/ref support!

I just tried it - there was only one piece of behavior I found
surprising. Here's a test that will fail:

public interface IMyThings
{
bool TryThis(string aString, out int aInt);
}

[Test]
public void OutParameterNotCaptured()
{
var things = new Mock<IMyThings>();
int setupValue = 1;
things.Expect(x => x.TryThis("one", out
setupValue)).Returns(true);
setupValue = 100; // same variable
things.Expect(x => x.TryThis("one hundred", out
setupValue)).Returns(false);

int newValue;
things.Object.TryThis("one", out newValue);

Assert.That(newValue, Is.EqualTo(1));
}


It looks like the closure is capturing the variable (setupValue in
this example), so the assert fails (it gets 100, the current value of
setupValue). The second call to Expect is really extraneous to the
test; it's just an example of why someone would change the value of
the out parameter variable.

The workaround is simple - don't change the original variable, and
declare a new one (int setupValue2) for each call to Expect. This
definitely qualifies as a "gotcha," and it would be great if a future
release could prevent it. If that's not possible, perhaps a caution
could be added to the documentation/quickstart.

Thanks again!
Bill Sorensen

On Sep 29, 12:18 pm, "Daniel Cazzulino" <dan...@cazzulino.com> wrote:
> the coolest thing (IMO) is that whichever the value of the variable you pass
> as out/ref, that's the value that will be returned/set when the method is
> invoked :D
>
> On Mon, Sep 29, 2008 at 2:16 PM, Daniel Cazzulino <dan...@cazzulino.com>wrote:
>
> > The best example I can think of:
>
> >http://code.google.com/p/moq/source/browse/trunk/UnitTests/OutRefFixt...
>
> > :)

Daniel Cazzulino

unread,
Oct 8, 2008, 12:53:23 PM10/8/08
to moq...@googlegroups.com
ahhh... good catch!
I was trying to think where in the API we were doing lazy evaluation without lamda syntax, and this is it!
Of course you cannot have a lambda for the out/ref, so there's no choice but to pick an option :)

For consistency, I think it should actually capture the value, and maybe we can add a .LazyEvaluation() after the expectation if you want difrerent behavior?

TrueWill

unread,
Oct 8, 2008, 9:54:24 PM10/8/08
to Moq Discussions
Doesn't capturing equal LazyEvaluation?

Daniel Cazzulino

unread,
Oct 8, 2008, 10:54:26 PM10/8/08
to moq...@googlegroups.com
ok, I meant resolve/evaluate/freeze the value at expectation setup time.

TrueWill

unread,
Oct 9, 2008, 8:38:37 PM10/9/08
to Moq Discussions
Maybe ImmediateEvaluation?

On Oct 8, 9:54 pm, "Daniel Cazzulino" <dan...@cazzulino.com> wrote:
> ok, I meant resolve/evaluate/freeze the value at expectation setup time.
>

Daniel Cazzulino

unread,
Oct 9, 2008, 9:14:55 PM10/9/08
to moq...@googlegroups.com
but then that would mean that by default we'd do lazy evaluation? that's the opposite of what we do now...

which one do you think is the most obvious behavior? (remember that for Returns(...) we cannot do lazy evaluation unless you use lambda version, because the compiler would resolve that and just call our API with the value, and we don't get an expression at all...

TrueWill

unread,
Oct 10, 2008, 11:05:51 PM10/10/08
to Moq Discussions
Sorry, I'm confused. Initially you wrote:

"For consistency, I think it should actually capture the value, and
maybe we
can add a .LazyEvaluation() after the expectation if you want
difrerent
behavior?"

Just so we're totally clear, what we're talking about is a captured
outer variable in a closure. For the most part, I like the way Moq
handles these currently. It makes methods like Callback() extremely
easy to use - you generally want a callback delegate to affect the
outer scope. I think of closures as lazy-evaluated, as the captured
variable's value is accessed when the delegate is invoked, not when
the delegate is created. So to me, the default behavior of Moq (when
lambdas are used) is lazy evaluation. Please correct me if I'm
mistaken.

(I'm not trying to be pedantic, just precise. I'm having to cross-
reference Skeet's "C# in Depth" to get the terminology right.)

Really, the only time I've run into surprises with Moq's use of
lambdas is with out/ref parameters. My personal feeling is that adding
LazyEvaluation() or ImmediateEvaluation() would only confuse people
(hey, it confused me), and that changing the current behavior for
other methods (Callback(), Returns()) would be detrimental.

One possibility you might consider is adding a different syntax for
setting out parameters. The current syntax confuses ReSharper - it
thinks the initial value assigned to the variable used with the out
parameter is never used, and many programmers would also suspect this.
I personally feel that this is one of the few places where Rhino Mocks
syntax is clearer, with .OutRef("value") used to set the out parameter
value. It's not like Ayende hasn't borrowed from you before... ;-)

Anyway, my two cents.
Thanks!
Bill Sorensen

On Oct 9, 8:14 pm, "Daniel Cazzulino" <dan...@cazzulino.com> wrote:
> but then that would mean that by default we'd do lazy evaluation? that's the
> opposite of what we do now...
>
> which one do you think is the most obvious behavior? (remember that for
> Returns(...) we cannot do lazy evaluation unless you use lambda version,
> because the compiler would resolve that and just call our API with the
> value, and we don't get an expression at all...
>

Daniel Cazzulino

unread,
Oct 11, 2008, 8:54:05 AM10/11/08
to moq...@googlegroups.com, Moq Discussions
You got it right, and I was using confusing terminology

.OutRef is not compile-safe so that's why I prefer not to use that...

Sent from my iPod

TrueWill

unread,
Oct 11, 2008, 11:09:42 AM10/11/08
to Moq Discussions
I'm fine with Moq the way it is. You have the current behavior
documented on the QuickStart. You can always add to it later if a more
elegant solution suggests itself.

Thanks for discussing this!
Bill Sorensen
Reply all
Reply to author
Forward
0 new messages