+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 On Sat, Aug 21, 2010 at 1:19 AM, David Tchepak <[email protected]> wrote: > 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...@googlegroups.com> >> > > <rhinomocks%2bunsubscr...@googlegroups.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...@googlegroups.com> >> > > <rhinomocks%2bunsubscr...@googlegroups.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...@googlegroups.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]<rhinomocks%[email protected]> > . > 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 -- 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.
