Mock Base Calls Up the Inheritance Chain?

2,146 views
Skip to first unread message

Scott Klarenbach

unread,
Sep 26, 2008, 7:07:02 PM9/26/08
to moq...@googlegroups.com
I have a ServiceB that inherits from ServiceA.

ServiceB has a method "Create()" which does the following:

{
   Initialize();
   Validate();
   base.Create();
}

I want to test the "real" ServiceB's Create method, but I want to mock away ServiceB's base.Create() call.

Is this possible to do?

--
Talk to you soon,

Scott Klarenbach

PointyHat Software Corp.
www.pointyhat.ca
p 604-568-4280
e sc...@pointyhat.ca
#200 - 3466 W. Broadway
Vancouver, BC V6R2B3

_______________________________________
To iterate is human; to recurse, divine

Daniel Cazzulino

unread,
Sep 27, 2008, 1:56:41 AM9/27/08
to moq...@googlegroups.com
yup, just create a mock of ServiceB, setup the CallBase = true, but set an expectation fothe members you want to mock away. Other members will call the base default implementation.

HTH
/kzu

Scott Klarenbach

unread,
Sep 27, 2008, 1:39:22 PM9/27/08
to moq...@googlegroups.com
Hi,

That doesn't seem to work, or I'm misunderstanding something.

var servB = new Mock<ServiceB>() {CallBase = true};
// how to tell Moq that this expectation is for the Parent and not the mock.Object?
servB.Expect(serv => serv.Create(It.IsAny<EntType>())).Returns(1);

// now, how do I call the derived object's Create method?
servB.Object.Create(myEnt);

// this of course fires the mocked method from the base, and not the derived Object's overrident implmentation


What I'm trying to do, is test Service B's "Create" method, but mock it's parent's base.Create method.

Thanks.

Daniel Cazzulino

unread,
Sep 27, 2008, 5:11:11 PM9/27/08
to moq...@googlegroups.com
I thought your scenario was to test a method on a B that invokes *another* method on the base class.

What you're trying to do is not possible (setting an expectation for a method and manually invoking the same method on the base class).

I'd like to understand more about why you need to do such a thing. Sounds a bit weird as a testing pattern... the behavior of the base class should be tested on its own fixture...

Scott Klarenbach

unread,
Sep 29, 2008, 10:52:13 AM9/29/08
to moq...@googlegroups.com
Exactly.  That's what I'm trying to do is test the behaviour of the base class on it's own, and the behaviour of the child class on it's own.  For now, let's forget about the base class.


What you're trying to do is not possible (setting an expectation for a method and manually invoking the same method on the base
You've got it backwards.  I'm trying to test the method on B, and have an expectation fire for A.  B overrides A's method.  I test A seperately, but I cannot test B independently it seems, without A firing.  This seems like a very common requirement to me.

Your suggestion will only work if it's not an override.  So I can setup expectations on the base methods, but how can I do this in an override scenario?  I think it's a limiation of Moq at the moment, but I don't fully understand it so I want make sure I'm not missing something.

class B : A
{
  public override void Create(Entity ent)
  {
    ent.ID = 1;
    base.Create(ent);
  }
}

I want to test B and Assert that ent.ID == 1.  How can I mock B's parent (A)'s Create method?  I want the call to base.Create(ent) inside of B to be mocked.  I DONT' want to test A's method.  A is the parent class, and I test it separately.  But how can I test the REAL method of Create in the child class B, and mock any calls inside to the parent class A?

Thanks.

Daniel Cazzulino

unread,
Sep 29, 2008, 1:11:32 PM9/29/08
to moq...@googlegroups.com
ah, got it.

you cannot do that with Moq, or with your own custom manual mock either. So it's more a limitation of the language/runtime than Moq, I think.

if you can come up with a way to do the same with plain C# code, I'd be glad to give it a try implementing it with moq/dynamicproxy...

Scott Klarenbach

unread,
Sep 29, 2008, 1:14:37 PM9/29/08
to moq...@googlegroups.com
ok thanks.

I'm curious: how are other people testing these child classes in isolation of their parent classes, when the child classes are overriding the parent's virtual members?

The working solution I have is that I have to test the parent class as well, at the same time, by providing all of its dependencies, and setting up all the expectation that base.Create() might need.  This is redundant though, as the parent was already tested, not to mention the fact that it makes the child tests much bigger than they need to be.

Thanks.

Brian J. Cardiff

unread,
Sep 29, 2008, 1:32:35 PM9/29/08
to moq...@googlegroups.com
My two cents...

Not sure if one of the following applies, It depends on what you are trying to test.

Option a)
Enforce using protected virtual methods (which can be tested by Moq).

class A {
 public void Create(Entity e) {
    this.DoStuff(Entity e);
    // do more things here
 }
 protected virtual DoStuff(Entity e){ /* Or throw NotImplementedException(); if appropriate */ }
}

class B {
 protected override DoStuff(Entity e){
   e.Id = ...
 }
}

this way you don't allow Create to be overriden and not be called. This seems to be your design decision, so you can enforce it in the code rather that in a convention.

Option b)
Build your test for base class and run it them on all inheritors/implementors.
This way you could test behavior rather than messages being sent.
--
Brian J. Cardiff
bcardiff(?)gmail.com
.
Reply all
Reply to author
Forward
0 new messages