Ayende,
it's of course very nice to be able to "Do" in AssertWasCalled. But -
I still think it would be nice to test argument values as easy as one
can define constraints.
Instead of
AssertWasCalled(
x => x.foo(Arg<int>.Is.Any),
o => o.Do( invoke =>
{
Assert.AreEqual(7, invoke.Arguments[0])
}));
AssertWasCalled(
x => x.foo(Arg<int>.Is.Any),
o => o.Do( invoke =>
{
Assert.IsTrue(invoke.Argument[0] > 2)
}));
Just this:
AssertWasCalled(
x => x.foo(Arg<int>.Is.Any),
o => o.AssertArguments(7));
AssertWasCalled(
x => x.foo(Arg<int>.Is.Any),
o => o.AssertArguments(Is.GreaterThan(2)));
On 2 Okt., 19:27, "Ayende Rahien" <[EMAIL PROTECTED]> wrote:
> AssertWasCalled( x=>x.Foo(null), o=>o.Do(...) );
>
> On Thu, Oct 2, 2008 at 5:56 PM, ssteinegger <[EMAIL PROTECTED]> wrote:
>
> > Actually, my solution is not very good, it is not much better than Do.
> > What actually would really be annoying with Rhino 3.5 is that Do
> > { Assert } breaks the AAA paradigm. The arguments should ideally be
> > asserted in the last part of the test, where the other Asserts are. It
> > should not be much of a difference if the values are visible to the
> > caller (you test them at the end) or not (you need to test them by the
> > mock). Don't ask me for a syntax for that, this wouldn't be easy at
> > all.
>
> > On 1 Okt., 17:16, "Shane Courtrille" <[EMAIL PROTECTED]>
> > wrote:
> > > Actually now that I think about it a capturing constraint is better then
> > Do
> > > for this scenario.
>
> > > On Wed, Oct 1, 2008 at 7:54 AM, Shane Courtrille
> > > <[EMAIL PROTECTED]>wrote:
>
> > > > I personally use a Do to capture the object and assert directly against
> > > > it. Now if only I could figure out a way to use Do without having to
> > create
> > > > a custom delegate every time...
>
> > > > On Wed, Oct 1, 2008 at 7:19 AM, ssteinegger <[EMAIL PROTECTED]>
> > wrote:
>
> > > >> Ok, I just can use Do. My second solution isn't actually far from
> > > >> that.
>
> > > >> I just tried to make it more explicit, probably even more declarative.
> > > >> More like "check-for-argument-values-here" than "execute-some-custom-
> > > >> code-here". Everything you can find by name in an API, you don't have
> > > >> to explain to the people. IMHO, it is not obvious how to assert for
> > > >> argument values.
>
> > > >> What are other people thinking about that?
>
> > > >> On 1 Okt., 12:38, "Ayende Rahien" <[EMAIL PROTECTED]> wrote:
> > > >> > You can use a Do to do that, that is what it is for.
>
> > > >> > On Wed, Oct 1, 2008 at 1:15 PM, ssteinegger <[EMAIL PROTECTED]>
> > > >> wrote:
>
> > > >> > > I would like to make a difference between "Filtering" and
> > "Asserting"
> > > >> > > arguments of expected calls.
>
> > > >> > > The problem is, there is an important difference between
> > "Filtering"
> > > >> > > and "Asserting". "Filtering" means, the expectation only matches
> > if
> > > >> > > all the criteria match. This is defined with the classical
> > Constraints
> > > >> > > or the inline Arg's.
>
> > > >> > > Asserts are if you test that some values are correctly passed to
> > the
> > > >> > > expected call.
>
> > > >> > > Until now, with Rhino.Mocks 3.4 I also use the Constraints as
> > > >> > > "Asserts". I wrote expectations like this:
>
> > > >> > > LastCall.Constraints(
> > > >> > > Is.TypeOf<TestObject>()
> > > >> > > && Property.ValueConstraint("BusinessId",
> > > >> > > Is.NotEqual(Guid.Empty))
> > > >> > > && Property.Value("LatestVersionNumber", (long)1)
> > > >> > > && Property.ValueConstraint("ReleasedVersion",
> > > >> Is.Null())
> > > >> > > && Property.ValueConstraint("ProposedVersion",
> > > >> > > Property.Value("VersionNumber", (long)1))
> > );
>
> > > >> > > This works quite well, you can define whole object graphs with the
> > > >> > > constraints. I have many such constraints when mocking the data
> > access
> > > >> > > layer. Some entities are created in the unit under test, stored in
> > > >> > > database and never visible to the caller.
>
> > > >> > > The fundamental problem is the message I get when a value is
> > wrong. I
> > > >> > > get something like "IGeneralDataAccess.Store( <all the
> > constraints> );
> > > >> > > Expected #1, Actual #0.
>
> > > >> > > This is not the information I need. To find out what actually has
> > been
> > > >> > > passed, I need to debug. I would like to have a message like
> > > >> > > "Argument Assertion failed: IGeneralDataAccess.Store(
> > <constraints> ),
> > > >> > > argument 0 - property ProposedVersion - property VersionNumber
> > > >> > > expected 1, actual 0."
>
> > > >> > > I found this blog (
> >http://ayende.com/Blog/archive/2008/07/02/Rhino-
> > > >> > > Mocks-3.5-A-feature-to-be-proud-of.aspx<
> > > >>http://ayende.com/Blog/archive/2008/07/02/Rhino-Mocks-3.5-A-feature-t
> > ..
> > > >> .>)
> > > >> > > from Ayende mentioned in
> > > >> > > another discussion.
> > > >> > > With Rhino.Mocks 3.5 I can do this:
>
> > > >> > > dataAccessMock
> > > >> > > .Stub(x => x.Store(Arg<object>.Is.TypeOf<TestObject>()))
> > > >> > > .Do(invocation =>
> > > >> > > {
> > > >> > > // get the argument and cast it
> > > >> > > TestObject entity = invocation.Arguments[0] as TestObject;
> > > >> > > Assert.AreNotEqual<Guid>(Guid.Empty, entity.BusinessId);
> > > >> > > Assert.AreEqual<long>(1, entity.LatestVersionNumber);
> > > >> > > // ... and so on
> > > >> > > });
>
> > > >> > > Without trying it myself, it should work fine. It matches the
> > > >> > > expectation and asserts the arguments afterwards. This syntax is
> > > >> > > indeed not very intuitive, and only few people will ever use it.
> > (IMO,
> > > >> > > Do should usually not be used, because mocks should not contain
> > logic.
> > > >> > > Except for some special cases, Do has some smell for me.)
>
> > > >> > > I would like something as follows:
>
> > > >> > > dataAccessMock
> > > >> > > .Stub(x => x.Store(Arg<object>.Is.TypeOf<TestObject>()))
> > > >> > > .AssertArguments(
> > > >> > > Property.ValueConstraint("BusinessId", Is.NotEqual(Guid.Empty))
> > > >> > > && Property.Value("LatestVersionNumber", (long)1)
> > > >> > > ...
> > > >> > > );
>
> > > >> > > (I know there is a better syntax for the properties that does not
> > use
> > > >> > > the property names in strings. But i don't know how to use it when
> > > >> > > having more then one criteria.)
>
> > > >> > > -- OR --
>
> > > >> > > dataAccessMock
> > > >> > > .Stub(x => x.Store(Arg<object>.Is.TypeOf<TestObject>()))
> > > >> > > .Arguments(
> > > >> > > (TestObject entity) =>
> > > >> > > {
> > > >> > > // Test-Framework asserts
> > > >> > > Assert.AreNotEqual<Guid>(Guid.Empty, entity.BusinessId);
> > > >> > > Assert.AreEqual<long>(1, entity.LatestVersionNumber);
> > > >> > > // ... and so on
> > > >> > > }
> > > >> > > );
>
> > > >> > > I think I'd prefer the last one. It is simpler to implement and
> > > >> > > simpler to use - except that it does not tell the user explicitly
> > that
> > > >> > > he most likely should write Assert's in the lamda expression.
>
> > > >> > > Actually, it's nothing more than "Do" with an action for each
> > > >> > > argument. Very simple.
>
> > > >> > > Ayende, what do you think about that? I could write another patch.
>
>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Rhino.Mocks" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/RhinoMocks?hl=en
-~----------~----~----~----~------~----~------~--~---