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
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 >>
You can use the following syntax:
Mock.Arrange(() => Arg.IsAny<ParentClass>().Sum()).Returns(2);
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.
Mock.ArrangeSet(()=>Arg.IsAny<ParentClass>().MyProperty = newValue).OccursOnce();
but Arg.IsAny<ParentClass>() evaluates to null which causes a NullReferenceException.
Can you advise?
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.
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
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.
Dave
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
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.
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
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.
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.