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
-~----------~----~----~----~------~----~------~--~---