This is a migrated thread and some comments may be shown as answers.

How to mock base class method?

13 Answers 5515 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
cecilUOA
Top achievements
Rank 1
cecilUOA asked on 15 Nov 2011, 05:16 AM

It's quite common that we will try to customise a Framework class but still reuse most of the logic from the base class. For example, we want to provide our own Navigation Provider inheriting from Microsoft.SharePoint.Navigation.SPNavigationProvider. And we want to override GetChildNodes class to add some addition site map node on top of the collection that base class return. So we will be calling base.GetChildNodes() from our GetChildNodes method.

Here is a simple example. The problem is I dont know how to reference the base class method in the Mock.Arrange method?

public class ParentClass
{
    public virtual int Sum()
    {
        return 0;
    }
}
public class ChildClass : ParentClass
{
    public override int Sum()
    {
        return 1 + base.Sum();
    }
}
[TestMethod]
public void RunChildClass()
{
    var childClass = new ChildClass();
    Mock.Arrange(() => childClass.Sum()).Returns(2); // want to override ParentClass.Sum(), not ChildClass.Sum().
    var result = childClass.Sum();
    Assert.IsTrue(result == 3); // instead I will get 2 here.
}

13 Answers, 1 is accepted

Sort by
0
Ricky
Telerik team
answered on 17 Nov 2011, 03:08 PM
Hi Doug,

Thanks again for making the query. The new Q3 release is out and this release let you ignore the target instance for a specific setup.

Therefore you can rewrite the test in the following way:
Mock.Arrange(() => new ParentClass().Sum()).Returns(2).IgnoreInstance();
 
var childClass = new ChildClass();
 
var result = childClass.Sum();
 
Assert.IsTrie(result == 3);

Here you are setting the expected return for ParentClass regardless of its instance where it is  inherited by ChildClass and ChildClass can access it via base keyword from a method.

Hope that solves your issue.

Kind Regads,
Mehfuz
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Dave
Top achievements
Rank 1
answered on 27 Jan 2015, 05:40 PM
Is there some way of doing this when the base class is abstract?
0
Stefan
Telerik team
answered on 28 Jan 2015, 01:53 PM
Hello Dave,

You can use the following syntax:
Mock.Arrange(() => Arg.IsAny<ParentClass>().Sum()).Returns(2);
The above implies IgnoreInstance(), so you don't have to write it explicitly.

Regards,
Stefan
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Dave
Top achievements
Rank 1
answered on 29 Jan 2015, 11:35 AM
Hi Stefan. I tried that but it doesn't seem to work. I'm actually doing an ArrangeSet:

    Mock.ArrangeSet(()=>Arg.IsAny<ParentClass>().MyProperty = newValue).OccursOnce();

but Arg.IsAny<ParentClass>() evaluates to null which causes a NullReferenceException.
Can you advise?
Dave
0
Stefan
Telerik team
answered on 30 Jan 2015, 02:53 PM
Hi Dave,

It appears that It is not possible to tell JustMock to arrange the base implementation of a virtual setter in an abstract class.

I have logged the issue and I predict that it will be fully fixed in this year's Q2 release when the JustMock API is fully migrated to .NET 4.

In the interim I can only suggest that you make a dummy non-abstract derived class from ParentClass and go:
Mock.ArrangeSet(() => new DummyClass().Value = 5).IgnoreInstance().DoInstead(...)


Regards,
Stefan
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Dave
Top achievements
Rank 1
answered on 30 Jan 2015, 04:56 PM
Nope, this just isn't working.
Forget the abstract base class for a minute. Going back to the orginal question, and Mehfuz's answer, how would you do this if ParentClass doesn't have a default constructor?
Dave
0
Stefan
Telerik team
answered on 04 Feb 2015, 06:56 AM
Hello Dave,

If ParentClass doesn't have a default constructor, or if ParentClass is an abstract type, then in either case you can arrange against a mock of ParentClass:
var dummy = Mock.Create<ParentClass>();
Mock.ArrangeSet(() => dummy.Value = Arg.AnyInt).IgnoreInstance().DoInstead(...);


Regards,
Stefan
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Dave
Top achievements
Rank 1
answered on 11 Feb 2015, 03:30 PM
Thanks Stefan. That works a treat.
Dave
0
Dave
Top achievements
Rank 1
answered on 16 Feb 2015, 04:34 PM
Hi Stefan
Unfortunately I spoke too soon. It works in principle but there seems to be a problem with it under certain circumstances. I've tracked it down as far as I can and I've found that if a partial mock is arranged on some other member of the class under test, the mock of the base class method doesn't work, in that it actually mocks out the method for the derived class as well as for the base class.
I've set up a small demonstration project that illustrates this very clearly. I was going to attach it as a .ZIP file to this post but it seems only graphics file are allowed as attachments. If you tell me the best method to send it to you, I will.
This would be a really useful technique and I would be most grateful if you could have a look and tell me if there is a work-around for the problem.
FYI I am using JustMock version 2014.1.1424.1.
Thanks
Dave
0
Kaloyan
Telerik team
answered on 19 Feb 2015, 03:52 PM
Hello Dave,

You will need to use a support ticket to attach an archive file. Unfortunately, at this stage you are not assigned as a JustMock licensed user, which will prevent you from using our private support channel. You will either have to ask the license holder to add you as a licensed user and then open a new support ticket on the same matter, or simply use another way for sending us the files. For example, you can upload them to DropBox and send us the link.

Regards,
Kaloyan
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Dave
Top achievements
Rank 1
answered on 26 Feb 2015, 09:55 AM
Hi Stefan/Kaloyan
I am in the process of getting a licence from my company, but the admin takes a while. In the meantime the demonstration can be downloaded from http://www.knoware.co.uk/MockBaseClassProblem.zip
I'd appreciate it if you could take a look.
Dave
0
Zdravko
Telerik team
answered on 03 Mar 2015, 12:16 PM
Hello Dave,

Thank you for sharing the project with us.
We will review it in shortest terms possible and write you back.

Regards,
Zdravko
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Stefan
Telerik team
answered on 04 Mar 2015, 09:04 AM
Hi Dave,

Apparently this is a bug in JustMock. When dispatching mock calls, it does not distinguish between base and derived methods and applies all arrangements on every method in the inheritance chain to all methods in the chain. The first test works, because the call to the derived method does not go through JustMock, only the base call does.

This looks like a deeply ingrained defect (or feature turned defect), so it may take a while to fix. As a token of gratitude for providing us with such a great repro, I've given you some Telerik points.

Unfortunately, this time there is no workaround that I can think of.

Regards,
Stefan
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
Tags
General Discussions
Asked by
cecilUOA
Top achievements
Rank 1
Answers by
Ricky
Telerik team
Dave
Top achievements
Rank 1
Stefan
Telerik team
Kaloyan
Telerik team
Zdravko
Telerik team
Share this question
or