Difference between t.Stub and t.Expect

67 views
Skip to first unread message

Fabien Arcellier

unread,
Dec 6, 2009, 4:25:15 PM12/6/09
to Rhino.Mocks
Hello,

I have rewritten every exemple in the documentation exemple by using
AAA syntax (arrange, act, assert).
There is one things I don't understand.

What is the difference between the t.Stub<> and t.Expect<> ?

According to the documentation comments in RhinoMocksExtention.cs,
Stub doesn't create any expectation.

What does it means ?
Do you have an article to detail what is the expectation contest ?


One exemple to illustrate my question with Expect :

[Test]
public void setReturnValueWhateverArguments_AAA()
{
//Assert
this.view.Replay();
this.view.Expect(v => v.Ask(null, null)).Return
(null).IgnoreArguments();

//Act
object obj = this.view.Ask("1", null);

//Assert
Assert.AreEqual(null, obj);
this.view.VerifyAllExpectations();
}

One exemple to illustrate my question with Stub:

[Test]
public void setReturnValueWhateverArguments_AAA()
{
//Assert
this.view.Replay();
this.view.Stub(v => v.Ask(null, null)).Return
(null).IgnoreArguments();

//Act
object obj = this.view.Ask("1", null);

//Assert
Assert.AreEqual(null, obj);
this.view.VerifyAllExpectations();//I think this line is
not important in this case
}

Is there any difference on the interpretation ?

Do you have any article about this topic ?

Regards,
Fabien Arcellier

bill richards

unread,
Dec 6, 2009, 4:43:23 PM12/6/09
to Rhino.Mocks
AAA Syntax does not use Record()/Play()

// Arrange
var view = MockRepository.GenerateStub<IView>();
view.Stub(v => v.Ask(Arg<string>.IsAny, Arg<string>.IsAny)).Return
(null);

// Act
var result = view.Ask("1", null);

// Assert
Assert.That(result, Is.Null);

... but, the only thing about this test is .... it's only testing the
Mocking Framework (or is that the intention here?).

The test reads ...

// Arrange
Mocking framework generate a mock of the IView interface please.
Mocking framework, when I invoke IView.Ask(string, string), please pay
not attention to the values of the call, and give me a return value of
null

// Act.
Mocking framework, here's that method call I told you about

// Assert
Unit testing framework, please tell me if the Mocking framework gave
me a return value of null

On Dec 6, 9:25 pm, Fabien Arcellier <fabien.arcell...@gmail.com>
wrote:

Fabien Arcellier

unread,
Dec 6, 2009, 5:05:55 PM12/6/09
to Rhino.Mocks
Thanks for your reply. I understand all of it :)

These exemples are taken from the documentation and convert to follow
AAA pattern.
http://www.ayende.com/wiki/Rhino+Mocks+Method+Options+Interface.ashx

I have taken this test because it is very easy to understand.

I'd like to know the difference between to methods t.Stub<> and
t.Expect<> associate with a Mock object.

You only details the execution of stub method. What in the case of
Expect method ?
I got the same result in the two test (they pass)

It's this point I try to clarify.

Fabien

bill richards

unread,
Dec 7, 2009, 4:24:54 AM12/7/09
to Rhino.Mocks
As far as my understanding goes (so, this is only an opinion, I
guess), it seems that the difference between Stub and Expect is one of
style, though there are instances when you might not neccesarily want
to stub anything, and therefore Expect would be the member of
choice ...

An example:


// Arrange
var aggregator = MockRepository.GenerateStub<IEventAggregator>();
var event = MockRepository.GenerateStub<MyEvent>();
aggregator.Stub(a=>a.GetEvent<MyEvent>()).Return(event); // we know
that this is going to be called, we want to check the correct value is
returned

// Act
var objectUnderTest = new MyTestableObject(aggregator);

// Assert
Assert.That(objectUnderTest.Event, Is.EqualTo(event));

* NOTE * This is really about me knowing the internal workings of
MyTestableObject -maybe this object actually needs re-factoring
because it seems that "stuff" happens in the constructor. Another way
of testing this exact same code would be ....

// Arrange
var aggregator = MockRepository.GenerateStub<IEventAggregator>();
var event = MockRepository.GenerateStub<MyEvent>();
aggregator.Expect(a=>a.GetEvent<MyEvent>().Return(event); // we are
expecting that a.GetEvent<MyEvent>() will be called

// Act
var objectUnderTest = new MyTestableObject(aggregator);

// Assert
aggregator.VerifyAllExpectations();


On Dec 6, 10:05 pm, Fabien Arcellier <fabien.arcell...@gmail.com>
wrote:
> Thanks for your reply. I understand all of it :)
>
> These exemples are taken from the documentation and convert to follow
> AAA pattern.http://www.ayende.com/wiki/Rhino+Mocks+Method+Options+Interface.ashx
> > > Fabien Arcellier- Hide quoted text -
>
> - Show quoted text -

Patrick Steele

unread,
Dec 7, 2009, 9:24:53 AM12/7/09
to rhino...@googlegroups.com
I thought only mocks could verify expectations? Does that work for stubs too?

---
Patrick Steele
http://weblogs.asp.net/psteele

bill richards

unread,
Dec 7, 2009, 10:01:50 AM12/7/09
to Rhino.Mocks
Please find below a quick example I just put together.

It is of course entirely possible that I am wrongly interpreting the
passing of the second test.


namespace Example
{
public interface ITestItem { ITestChild Child { get; set; } }

public class TestItem : ITestItem
{

public TestItem(ITestChild child)
{
Child = child;
Child.SetParent(this);
}

public ITestChild Child { get; set; }
}

public interface ITestChild
{
ITestItem Parent { get; }
void SetParent(ITestItem item);
}

public class TestChild : ITestChild
{
public void SetParent(ITestItem item) { Parent = item; }
public ITestItem Parent { get; private set; }
}

[TestFixture]
public class TestItemFixture
{
[Test]
public void WhenUsingAStub_ShouldPassAssertionTest()
{
var child = MockRepository.GenerateStub<ITestChild>();

var item = new TestItem(child);
var actual = item.Child;


Assert.That(actual, Is.EqualTo(child));
}

[Test]
public void WhenUsingExpect_ShouldPassVerifyAllExpectations()
{
var child = MockRepository.GenerateStub<ITestChild>();
child.Expect(c => c.SetParent
(Arg<ITestItem>.Is.Anything));

new TestItem(child);

child.VerifyAllExpectations();
}
}
}

bill richards

unread,
Dec 7, 2009, 11:05:57 AM12/7/09
to Rhino.Mocks
I just modified the second test slightly, and it appears to indicate
that the Expectation was in fact realised.


[Test]
public void WhenUsingExpect_ShouldPassVerifyAllExpectations()
{
var child = MockRepository.GenerateStub<ITestChild>();
child.Expect(c => c.SetParent
(Arg<ITestItem>.Is.Anything));

var item = new TestItem(child);

child.VerifyAllExpectations();
child.AssertWasCalled(c => c.SetParent(item));
}

Tim Barcz

unread,
Dec 7, 2009, 12:45:30 PM12/7/09
to rhino...@googlegroups.com
Stubs can do expectations and I've stumbled on this many times as have others...there are numerous threads about this and I believe this was not the original intended behavior but rather an evolution over time.  That said, there has been significant discussion about moving away from the notion of "mocks" and "stubs" in RhinoMocks 4.0 to something a bit mroe clear.

       }

--

You received this message because you are subscribed to the Google Groups "Rhino.Mocks" group.
To post to this group, send email to rhino...@googlegroups.com.
To unsubscribe from this group, send email to rhinomocks+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/rhinomocks?hl=en.





--
Tim Barcz
Microsoft C# MVP
Microsoft ASPInsider
http://timbarcz.devlicio.us
http://www.twitter.com/timbarcz

Fabien Arcellier

unread,
Dec 7, 2009, 2:29:32 PM12/7/09
to Rhino.Mocks
Thanks all for your answer.

Finally I looked in the source code to verify the behavior of Stub<>
method :
I found this implementation :

/// <summary>
/// Tell the mock object to perform a certain action when a matching
/// method is called.
/// Does not create an expectation for this method.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="R"></typeparam>
/// <param name="mock">The mock.</param>
/// <param name="action">The action.</param>
/// <returns></returns>
public static IMethodOptions<R> Stub<T, R>(this T
mock, Function<T, R> action)
where T : class
{
return Expect(mock, action).Repeat.Times(0, int.MaxValue);
}

It seems the Stub<> method does a direct call to Expect method with
repeat option.

According to method commentary, this method doesn't create an
expectation.
In fact, we create it.

I don't understand the interest of Stub<> method ... It shouldn't
declared as deprecated ?

Regards,
Fabien Arcellier

On Dec 7, 5:45 pm, Tim Barcz <timba...@gmail.com> wrote:
> Stubs can do expectations and I've stumbled on this many times as have
> others...there are numerous threads about this and I believe this was not
> the original intended behavior but rather an evolution over time.  That
> said, there has been significant discussion about moving away from the
> notion of "mocks" and "stubs" in RhinoMocks 4.0 to something a bit mroe
> clear.
>
> On Mon, Dec 7, 2009 at 10:05 AM, bill richards <bill.richa...@greyskin.co.uk
>
>
>
>
>
> > wrote:
> > I just modified the second test slightly, and it appears to indicate
> > that the Expectation was in fact realised.
>
> >        [Test]
> >        public void WhenUsingExpect_ShouldPassVerifyAllExpectations()
> >        {
> >            var child = MockRepository.GenerateStub<ITestChild>();
> >            child.Expect(c => c.SetParent
> > (Arg<ITestItem>.Is.Anything));
>
> >             var item = new TestItem(child);
>
> >             child.VerifyAllExpectations();
> >            child.AssertWasCalled(c => c.SetParent(item));
> >         }
>
> > --
>
> > You received this message because you are subscribed to the Google Groups
> > "Rhino.Mocks" group.
> > To post to this group, send email to rhino...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > rhinomocks+...@googlegroups.com<rhinomocks%2Bunsubscribe@googlegrou ps.com>
> > .

Fabien Arcellier

unread,
Dec 7, 2009, 2:32:17 PM12/7/09
to Rhino.Mocks
To conclude, if I write some codes as examples, do you think that is
preferable to use Expect<> in place of Stub<> ?

On Dec 7, 7:29 pm, Fabien Arcellier <fabien.arcell...@gmail.com>
wrote:

Kam

unread,
Dec 21, 2009, 6:04:53 PM12/21/09
to Rhino.Mocks
I found a situation where I had to use x.Stub() rather than x.Expect
().

I do not know the reasons why. Maybe someone with more knowledge of
the Rhino MOcks engine could explain.

I found that when I used:

x.Expect(x => x.SomeProperty).Return(myProperty);

Reference to x.SomeProperty would only return myProperty within the
same unit. The moment I tried to push this stub into a class
constructor for another class, it returned NULL to that class.

I struggled with this, until I found x.Stub().

I replaced the line above for:

x.Stub(x => x.SomeProperty).Return(myProperty);

Please be aware that x.SomeProperty is a readonly property which is
why I needed to declare it this way.


If anyone could shed light on why this is necessary I would be
interested.

Thanks.

On Dec 7, 7:32 pm, Fabien Arcellier <fabien.arcell...@gmail.com>

Tim Barcz

unread,
Dec 21, 2009, 9:45:07 PM12/21/09
to rhino...@googlegroups.com
I would love to... However can you provide a test for me to comment on.

Tim

Sent from my iPhone

John Bierman

unread,
Dec 22, 2009, 12:36:28 AM12/22/09
to rhino...@googlegroups.com
Does the one that I sent you originally suffice?

To unsubscribe from this group, send email to rhinomocks+...@googlegroups.com.

Tim Barcz

unread,
Dec 22, 2009, 6:35:28 AM12/22/09
to rhino...@googlegroups.com, rhino...@googlegroups.com
I'd prefer something that compiles

Sent from my iPhone

Kam

unread,
Dec 22, 2009, 11:31:15 AM12/22/09
to Rhino.Mocks
I figured out the problem I was having. It appears that when I use
x.Expect - it is a 'once only' call. Once I've called it, I can't
call it again. This is why I couldn't see a problem when I ran the
tests. The tests call the operations once and work!

However, if I am trying to debug it and need to hover over properties
to find out what they hold, the thing goes pear shaped. Because when
I hover over the property, I have made that 'once only' call.

If I use, x.Stub though, it works as many times as I like!

Here is an example of what I was doing.

[TestFixture]
public class TestStubAgainstExpect
{
[Test]
public void TestStub()
{
var bin = MockRepository.GenerateStub<IBin>();
bin.Expect(x => x.IsFull).Return(false);

var dustBin = MockRepository.GenerateStub<IDustbin>();
dustBin.Expect(x => x.IsFull).Return(false);

var myHouse = MockRepository.GenerateStub<IHouse>();

//can not debug/hover over
myHouse.Expect(x => x.Bin).Return(bin);
myHouse.Expect(x => x.Dustbin).Return(dustBin);

//can debug/hover over
// myHouse.Stub(x => x.Bin).Return(bin);
// myHouse.Stub(x => x.Dustbin).Return(dustBin);


var cleaner = new Cleaner();
cleaner.EmptyTheBins(myHouse);
}
}

public class Cleaner
{
internal Cleaner()
{
}

public void EmptyTheBins(IHouse house)
{
if (house.Bin.IsFull)
{
//empty the bins
}
}
}

public interface IBin
{
bool IsFull { get;}
}

public interface IHouse
{
IBin Bin { get; }
IDustbin Dustbin { get; }
}

public interface IDustbin
{
bool IsFull { get; }
}

On Dec 22, 11:35 am, Tim Barcz <timba...@gmail.com> wrote:
> I'd prefer something that compiles
>
> Sent from my iPhone
>

> On Dec 21, 2009, at 11:36 PM, John Bierman <zkbier...@gmail.com> wrote:
>
>
>
> > Does the one that I sent you originally suffice?
>

> > On Mon, Dec 21, 2009 at 7:45 PM, Tim Barcz <timba...@gmail.com> wrote:
> > I would love to... However can you provide a test for me to comment  
> > on.
>
> > Tim
>
> > Sent from my iPhone
>

> > > For more options, visit this group athttp://groups.google.com/group/rhinomocks?hl=en
> > > .
>
> > --
>

> > You received this message because you are subscribed to the Google  
> > Groups "Rhino.Mocks" group.
> > To post to this group, send email to rhino...@googlegroups.com.
> > To unsubscribe from this group, send email to rhinomocks+...@googlegroups.com
> > .

> > For more options, visit this group athttp://groups.google.com/group/rhinomocks?hl=en
> > .
>
> > --
>

bill richards

unread,
Dec 22, 2009, 11:55:38 AM12/22/09
to Rhino.Mocks
Kam,

I could not fail to notice that you are not Asserting that your
expectations have been met!

i.e. :

[Test]
public void TestStub()
{
// Arrange


var bin = MockRepository.GenerateStub<IBin>();

// I would Stub this call instead of using Expect
bin.Stub(x => x.IsFull).Return(false);

var dustBin = MockRepository.GenerateStub<IDustbin>();

// I would Stub this call instead of using Expect
dustBin.Stub(x => x.IsFull).Return(false);

var myHouse = MockRepository.GenerateStub<IHouse>();

myHouse.Expect(x => x.Bin).Return(bin);
myHouse.Expect(x => x.Dustbin).Return(dustBin);

// Act


var cleaner = new Cleaner();
cleaner.EmptyTheBins(myHouse);

// Assert
// This line is missing
myHouse.VerifyAllExpectations();
}


But then again, I'm not entirely sure what is actually being
tested ....

My rule of thumb is as follows: If the object is not being tested, use
a Stub. If the object is being tested set an Expectation

So, in the example above, I have assumed that it is your IHouse
implementation that is being tested, and not the IBin or IDustbin
implementations.

Stub = when a particular member is invoked, I want x to happen
(every time).
Expect = when a particular member is invoked, I am expecting x to
occur.

Expectations can occur multiple times simply by using .Times(n), i.e.

myHouse.Expect(x => x.Bin).Return(bin).Times(2);

however, your test will fail with the call to
myHouse.VerifyAllExpectations(), since the call is only ever made once
(unless you are stepping through in debug mode and inspecting your
objects).

> > > .- Hide quoted text -

Kam

unread,
Dec 22, 2009, 5:50:08 PM12/22/09
to Rhino.Mocks
Sorry,

My example was pretty rushed and didn't explain what happened in
production. You are right, the example didn't seem to test anything.
But it did prove that x.Stub could be called many times and x.Expect
could only be called once.

If you change my example and make:

var bin = new Bin();

And bin is a property of house:

var house = new House();
house.Stub(x => x.Bin).Return(bin);

By using x.Stub instead of x.Expect, I can push house through a
business object that I am trying to test. That business object may
make modifications to bin and therefore call bin - as a property of
house - many times. Allowing me to test that bin comes out of the
business object with the data I expect.

I normally push a mocked/fake/stubbed data access layer into the
business object, so that I am testing the workflow through a business
layer. I don't believe this to be a 'unit' test, but it is still a
test I can run, using unit test methods.

On Dec 22, 4:55 pm, bill richards <bill.richa...@greyskin.co.uk>
wrote:

Kam

unread,
Dec 22, 2009, 5:54:09 PM12/22/09
to Rhino.Mocks
Sorry - i missed the end of you reply. Just read it through to the
end where you mentioned about the x.Expect.Return.Times(y).

I've never tried that, but it seems more granular and specific than my
'push my object through and hope the data is right when it comes out
the other end' way.

Thanks for that!


On Dec 22, 4:55 pm, bill richards <bill.richa...@greyskin.co.uk>
wrote:

> ...
>
> read more »

Reply all
Reply to author
Forward
0 new messages