Stubbing a void method

2,437 views
Skip to first unread message

samah

unread,
Aug 17, 2010, 3:36:38 PM8/17/10
to Rhino.Mocks
Hi all,

How can we stub a method that returns nothing using Rhino Mocks?

Thanks,

-Samah

Tim Barcz

unread,
Aug 17, 2010, 4:40:23 PM8/17/10
to rhino...@googlegroups.com
I presume since it returns nothing you mean "mock" a method.  I don't mean to be pedantic but what it sounds like you're trying to do is make sure something was called (this void method).  If that is the case you are wanting a mock.

If you confirm I'm correct (or correct me if I am wrong) I will quickly supply the code.

Tim


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

David Tchepak

unread,
Aug 17, 2010, 9:16:26 PM8/17/10
to rhino...@googlegroups.com
public interface IFoo {
  void DoFoo();
}

var foo = MockRepository.GenerateStub<IFoo>();

//Do something when void method is called:
foo.Stub(x => x.DoFoo()).WhenCalled(x => RunSomeCode());

//Assert void method was called
foo.AssertWasCalled(x => x.DoFoo());


Hope this helps.
Regards,
David

Tim Barcz

unread,
Aug 17, 2010, 9:18:51 PM8/17/10
to rhino...@googlegroups.com
pfft :-)

Tim Barcz

unread,
Aug 17, 2010, 10:11:38 PM8/17/10
to rhino...@googlegroups.com
Per my original email, I would actually suggest using a mock MockRepository.GenerateMock<IFoo>();

While you *can* assert on Stubs, it's muddied the waters a bit and the more semantically correct use is a Mock.

Tim

On Tue, Aug 17, 2010 at 8:16 PM, David Tchepak <tch...@gmail.com> wrote:

samah

unread,
Aug 18, 2010, 3:23:45 PM8/18/10
to Rhino.Mocks

Thanks for your replyes..

The senario I have is

public class fooClass {

public void methodToTest {

....
calls foo1
calls foo2
}

}


I want to test if the "methodToTest" calls foo2 but I don't want it to
break when calling foo1 and I want to use Partial Mocks because I want
the test to use the actual methods when not set in the expectations

[testMethod()]
public void test()
{
MockRepository mocks = new MockRepository();

fooClass fakeClass = mocks.PartialMock<fooClass>();

** fakeClass.Stub(x => x.foo1()).whenCalled(x => ;);

using(mocks.Record())
{
fakeClass.foo2();
}

mocks.Verify(fakeClass);

}

How do I Stub foo1 on line *, I don't want to assert anything against
it I just don't want to break my test becuase it is talking to an
outsource dependency?

Thanks,

Samah


On Aug 17, 9:11 pm, Tim Barcz <timba...@gmail.com> wrote:
> Per my original email, I would actually suggest using a mock
> MockRepository.GenerateMock<IFoo>();
>
> While you *can* assert on Stubs, it's muddied the waters a bit and the more
> semantically correct use is a Mock.
>
> Tim
>
>
>
>
>
> On Tue, Aug 17, 2010 at 8:16 PM, David Tchepak <tche...@gmail.com> wrote:
> > public interface IFoo {
> >   void DoFoo();
> > }
>
> > var foo = MockRepository.GenerateStub<IFoo>();
>
> > //Do something when void method is called:
> > foo.Stub(x => x.DoFoo()).WhenCalled(x => RunSomeCode());
>
> > //Assert void method was called
> > foo.AssertWasCalled(x => x.DoFoo());
>
> > Hope this helps.
> > Regards,
> > David
>
> > On Wed, Aug 18, 2010 at 5:36 AM, samah <samah.abumahm...@gmail.com> wrote:
>
> >> Hi all,
>
> >> How can we stub a method that returns nothing using Rhino Mocks?
>
> >> Thanks,
>
> >> -Samah
>
> >> --
> >> 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>
> >> .
> >> For more options, visit this group at
> >>http://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<rhinomocks%2Bunsubscribe@googlegrou­ps.com>
> > .
> > For more options, visit this group at
> >http://groups.google.com/group/rhinomocks?hl=en.
>
> --
> Tim Barcz
> Microsoft C# MVP
> Microsoft ASPInsiderhttp://timbarcz.devlicio.ushttp://www.twitter.com/timbarcz- Hide quoted text -
>
> - Show quoted text -

Tim Barcz

unread,
Aug 18, 2010, 9:43:15 PM8/18/10
to rhino...@googlegroups.com
Samah,

The code you want is below (I encourage you to paste into your code and run (note the use of xUnit)...a few notes however

  • I've used AAA syntax, which is our preferred method (over record/replay)
  • Since we're "stubbing" foo1 (that is intercepting calls made to it), it needs to be virtual.  Method foo2 does not have this requirement.
  • I'm using xUnit as the testing framework - this should translate very easily to MSTest (as it appears you are using)
  • The correct output of this program should be "I'm in foo2" - even though "I'm in foo1" coded into foo1, the call to it is intercepted.

Certainly if you have more questions, just ask.

Cheers,

Tim


public class FieldProblem_Samah
{
  [Fact]
  public void CanMockMethodWithEnvironmentPermissions()
  {
      // Arrange
      var mockedFoo = MockRepository.GeneratePartialMock<fooClass>();
      mockedFoo.Stub(x => x.foo1());

      // Act
      mockedFoo.methodToTest();

      // Assert
      mockedFoo.AssertWasCalled(x=>x.foo1());
  }
}

public class fooClass 
{

  public void methodToTest ()
  {
      foo1();
      foo2();
  }

  public virtual void foo1()
  {
      Console.WriteLine("I'm in foo1");
  }

  public void foo2()
  {
      Console.WriteLine("I'm in foo2");
  }

}

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

samah

unread,
Aug 20, 2010, 10:31:38 AM8/20/10
to Rhino.Mocks

Tim,

Thank you so much for your reply, I'm new to the world of testing and
I really appreciate your help..

In the real implementation of the method foo1 that I want to stub, the
code accesses a configuration file. I want to stub it in my test so
that it doesn't need to access a configuration file. I followed your
example and made foo1 virtual but on the line:

var mockedFoo = MockRepository.GeneratePartialMock<fooClass>();

and before stubbing the method I get an exception saying that the
method foo1 is trying to read a null object (which is the
configuration file.) I don't get this exception if I generate dynamic
or static mock of the class but I want to generate a partial mock. Any
idea? why is it seeing the production code?

Note: the method foo1 is called in the constructor of the fooClass(),
could that be it?

I have another question:

I'm assigned the task of creating unit tests for a System, I've been
learning about unit testing and I kind of understand the idea of
making the System testable to be able to do manual stubbing and
mocking. I'm still learning to use the Isolation framework Rhino
Mocks, My question is do I need to make the system testable the same
way I think about manual stubbing to be able to take advantage of
Rhino Mocks? in other words in terms of making the system testable
does it make a difference whether I'll be using manual stubbing &
mocking or using an isolation framework?

Thanks,

Samah


On Aug 18, 8:43 pm, Tim Barcz <timba...@gmail.com> wrote:
> Samah,
>
> The code you want is below (I encourage you to paste into your code and run
> (note the use of xUnit)...a few notes however
>
>    - I've used AAA syntax, which is our preferred method (over
>    record/replay)
>    - Since we're "stubbing" foo1 (that is intercepting calls made to it), it
>    needs to be virtual.  Method foo2 does not have this requirement.
>    - I'm using xUnit as the testing framework - this should translate very
>    easily to MSTest (as it appears you are using)
>    - The correct output of this program should be "I'm in foo2" - even

David Tchepak

unread,
Aug 21, 2010, 2:19:57 AM8/21/10
to rhino...@googlegroups.com
Hi Samah,

You've correctly identified the problem: the constructor will be called when you create the partial mock before you've stubbed it out.

You're also spot on that Rhino Mocks (and mocking frameworks in general) won't help you much with hard-to-test designs. I've found the best way to use mocking frameworks is just as a replacement for how I would normally write a manual mock or stub (in fact, that is how I recommend people start mocking: write manual mocks/stubs by hand until you get sick of it, then replace the manual code with calls to a mocking framework. The approach should remain the same). 

In terms of this specific problem, one way to deal with this is to extract foo1() into a new class or interface and inject it into the object via the constructor. I've called it IConfiguration because you mentioned it read a configuration file:

public class fooClass 
{
  IConfiguration configuration;
  public fooClass(IConfiguration configuration) {
    this.configuration = configuration;
  }
  public void methodToTest ()  {
      configuration.foo1();
      foo2();
  }
  public void foo2()  {
      Console.WriteLine("I'm in foo2");
  }
}

If you do a similar extraction for foo2() then you can get rid of the partial mock altogether, inject two fake objects into fooClass and test methodToTest() calls the dependencies properly. For example (excuse the names):

 [Fact]
  public void Example()  {
      // Arrange
      var configuration = MockRepository.GenerateMock<IConfiguration>();
      var secondDependency = MockRepository.GenerateMock<ISecondDependency>();
      var foo = new fooClass(configuration, secondDependency);

      // Act
      foo.methodToTest();

      // Assert
      secondDependency .AssertWasCalled(x=>x.foo2());
  }

When I run into the kind of problems you have just done (trying to partial mock things, stub values used in constructors etc.) I try and look at it as the tests trying to tell me that my design isn't working well for me. This can give you valuable clues as to how to refactor your code to make it easier to test, and as a result, more maintainable in future.

Regards,
David


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

Tim Barcz

unread,
Aug 22, 2010, 10:04:38 PM8/22/10
to rhino...@googlegroups.com
+1 to David's comments, Samah is this a bit clearer now?

Often to as a point of design  - you don't want to call virtual methods from the constructor - this can cause problems (outside of just test code).

Tim

samah

unread,
Aug 23, 2010, 11:51:01 AM8/23/10
to Rhino.Mocks

Tim & David,

Thank you so much for your replies. Yes it is much clearer now. I
thought I'll be able to do things using the mocking framework
withought changing my design as much as I need to change it for manual
testing but it it turns out that I should refactor it the same way. at
least I know I'm on the right path.

This group is a valuable place to get a good start with testing thank
you so much guys.

Samah
> >> > >www.twitter.com/timbarcz-Hidequoted text -
>
> >> > > > - Show quoted text -
>
> >> > > --
> >> > > 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>
> >> <rhinomocks%2Bunsubscribe@googlegrou­ps.com>
> >> > > .
> >> > > For more options, visit this group at
>
> ...
>
> read more »- Hide quoted text -

Tim Barcz

unread,
Aug 23, 2010, 11:57:38 AM8/23/10
to rhino...@googlegroups.com
" I thought I'll be able to do things using the mocking framework withought changing my design as much..."

There are solutions on the market which support this (see TypeMock), however in addition to tests running successfully one of the large reason I test and am a big proponent of testing is the better designs that comes through testing.  By making the changes David is suggesting you make, you can in the future be insulated from configuration changes.

I think the rigidity in some mocking frameworks (not being able to mock statics and protected methods) is largely a very very good thing.

Tim

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
Reply all
Reply to author
Forward
0 new messages