Need Help with Rhino Mocks {Changing method call inside of another method}

136 views
Skip to first unread message

alwaysgo

unread,
Jun 15, 2012, 1:16:55 AM6/15/12
to rhino...@googlegroups.com
Hi,

I need help figuring out how I can change the method call inside of another method.

For example:

public class A
 {
      public string getValue()
      {
           string retVal = "";
           B b = new B();
          
          retVal = b.getB();
          retVal = retVal + " Final ";
          return retVal;          
      }
}

public class B
{
   public string getB()
   {
      return "B";
   }
}

public class BStub
{
    public string getBStub()
    {
         return "BStub";
     }
}

public class TestDriver
{
   public static void Main()
   {
       A aClass = MockRepository.GenerateMock<A>();
       B bClass = MockRepository.GenerateStub<B>();
      
       bClass.Stub(x=>x.getB()).Return(new BStub().getBStub())
                                            .Do(new Func<string>(()=>new BStub().getBStub()));

       
       string result = aClass.getValue();  //I am not getting any value to result
                                                         //In this case, I want to get "BStub Final" after calling
                                                         // getValue() method on 'aClass'

    }

}

Any help would be appreciated.

Thanks


Patrick Steele

unread,
Jun 15, 2012, 8:44:41 AM6/15/12
to rhino...@googlegroups.com
You can't. At least not with Rhino.Mocks.

This really leads to a discussion on Inversion of Control (IOC) and
Dependency Injection (DI). What you have now is a hard dependency on
a new "B" inside A.getValue(). This makes maintenance and mods harder
in the long run. What I would suggest, and this would lead to more
testable code, is to pass in a factory interface to class A's
constructor. That factory will be responsible for creating B. By
doing it this way, you could inject a stub "B" by injecting a stub
factory. Something like this:

public interface IBeeFactory
{
B Create();
}

public class A
{
private readonly IBeeFactory bFactory;

public A(IBeeFactory bFactory)
{
this.bFactory = bFactory;
}

public string getValue()
{
string retVal = "";
B b = bFactory.Create();

retVal = b.getB();
retVal = retVal + " Final ";
return retVal;
}
}

Now your test can be something like this:

var factory = MockRepository.GenerateStub<IBeeFactory>();
factory.Stub(f => f.Create()).Return(new B());

var a = new A(factory);
Assert.AreEqual("BStubFinal", a.getValue());

NOTE: Just banged the code out quickly. Be wary of errors.

---
Patrick Steele
http://weblogs.asp.net/psteele
> --
> You received this message because you are subscribed to the Google Groups
> "Rhino.Mocks" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/rhinomocks/-/lvq3GMbEl9cJ.
> 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.

alwaysgo

unread,
Jun 15, 2012, 1:16:53 PM6/15/12
to rhino...@googlegroups.com
Thank you for providing this information. We were planning to use the Rhino Mocks for legacy code that we cannot change and now I understood we have to find different ways to test that legacy code. 

Again, thank you for your help on this topic.
> For more options, visit this group at
> http://groups.google.com/group/rhinomocks?hl=en.
> rhinomocks+unsubscribe@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/rhinomocks?hl=en.
> rhinomocks+unsubscribe@googlegroups.com.

Gavin van der Merwe

unread,
Jun 15, 2012, 9:40:13 PM6/15/12
to rhino...@googlegroups.com
Dude, 

Just to add my 2 cents. You should NOT be applying Mock Level Unit TDD to code has not already applied DI(dependancy injection) or IoC(inversion of control) especially if you are using proxy based aspect oriented frameworks(thanks fowler for fucking that up). 

What this means is unless you are new'ing up via the constructor(by injecting your dependencies there) and making your members public/virtual you CANNOT apply any kind of unit level testing period using mocking today. Especially not with Rhino Mocks. 

Do not bother. Your best bet is actually buying a product that can do IL Weaving which can rewrite IL calls on the fly. Something I have done myself using by writing my own framework that uses mono cecil or by buying typemock isolator.

I am tired of hearing MVP'S promoting dead bullshit open source products on the basis "good practice" when in fact it is fundamentally flawed or require massive infrastructural reworks.We all live in the real world and knowledge is power.

Look at:

Mono Cecil (If you are brave enough to do IL weaving, thanks JB!)
Typemock Isolator (If you cannot be bothered and have budget)
Pex and Moles (If you need something quick but are willing to absorb a massive hump of pain)

Seriously man, changing your object protection levels(restructuring your calls) and increasing the load on the VER by using keywords like virtual guarded by interfaces is not the answer. I dont care what anyone says. It is not efficient at all. 

@Patrick - This is not a dig at you at all I think you are awesome. Except I do believe we should delete this project and we forget that this travesty ever raped Dave Broman's design.

Sorry for sounding like a cantankerous git!!! :)

To view this discussion on the web visit https://groups.google.com/d/msg/rhinomocks/-/alB8-L1LukIJ.

To post to this group, send email to rhino...@googlegroups.com.
To unsubscribe from this group, send email to rhinomocks+...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages