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


On Sat, Aug 21, 2010 at 12:31 AM, samah <[email protected]> wrote:

>
> 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 <[email protected]> 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
> >    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");
> >   }
> >
> >
> >
> >
> >
> > }
> > On Wed, Aug 18, 2010 at 2:23 PM, samah <[email protected]>
> wrote:
> >
> > > 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 <[email protected]> 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 <[email protected]>
> > > 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 <[email protected]
> >
> > > 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 [email protected].
> > > > >> To unsubscribe from this group, send email to
> > > > >> [email protected]<rhinomocks%[email protected]>
> <rhinomocks%2bunsubscr...@googlegrou­ps.com>
> > > <rhinomocks%2bunsubscr...@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 [email protected].
> > > > > To unsubscribe from this group, send email to
> > > > > [email protected]<rhinomocks%[email protected]>
> <rhinomocks%2bunsubscr...@googlegrou­ps.com>
> > > <rhinomocks%2bunsubscr...@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 -
> >
> > > --
> > > 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]<rhinomocks%[email protected]>
> <rhinomocks%2bunsubscr...@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 -
>
> --
> 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]<rhinomocks%[email protected]>
> .
> 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 [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.

Reply via email to