I have a base class with a protected method that's being called in a public method in the child class I want to test. I'm failing to find a way to moq the base protected method for easier testing in child class.
public class MyBaseClass
{
protected virtual bool MyMethod(int number)
{
return number == 1;
}
}
public class MyChildClass : MyBaseClass
{
public bool DoSomething(int number)
{
return MyMethod(number);
}
}
[TestFixture]
public class MyChildClassTests
{
[Test]
public void Expected_Returns_False_WhenPassed_1()
{
var myChildClass = new MyChildClass();
// How do I mock MyMethod used in myBaseClass here?
// var mock = new Mock<MyBaseClass>();
// mock.Protected().Setup<bool>("MyMethod", ItExpr.IsAny<int>()).Returns(false);
// The above mock is correct, but it's in a different instance object than myBaseClass
var result = myChildClass.DoSomething();
Assert.AreEqual(false, result);
}
}
I can't change the classes to have a better architecture and I must do the best I can to implement unit test for DoSomething(), what I did so far is mock and prepare all the data that method uses, but since it's in another class I'd love my MyChildClassTests to not do all that and just limit to test DoSomething().
I've read about partial mocking and a whole lot of other questions and answers and I can't get it to work right.
I appreciate any suggestions!
Edit: Forgot to put public in all the classes, in my real world case, they are public.
class MyChildClassTests
{
[Test]
public void Expected_Returns_False_WhenPassed_1()
{
var myChildClass = new FakeChildClass();
var result = myChildClass.DoSomething(1);
Assert.AreEqual(false, result);
}
}
public class FakeChildClass: MyChildClass
{
protected override bool MyMethod(int number)
{
return number == 1;
}
}
First of all, ensure your classes are public.
Moq will complain about not being able to proxy into them if they're not.
public class MyBaseClass
{
public virtual bool MyMethod(int number)
{
return number == 1;
}
}
public class MyChildClass : MyBaseClass
{
public bool DoSomething(int number)
{
return MyMethod(number);
}
}
Next, make your base class method public. You won't be able to set it up unless you do.
After that, create a mock of the child object and mock the parent method.
var mockChild = new Mock<MyChildClass>(){CallBase = true};
mockChild.Setup(x => x.MyMethod(It.IsAny<int>())).Returns(false);
Pull your result.... result will return false even though the actual implementation would have returned true with 1 as a parameter.
var result = mockChild.Object.DoSomething(1);
When calling the DoSomething method, you'll actually enter the real implementation of that (put a breakpoint on if you don't believe me!) - but the mocked version of MyMethod will kick in.
Thanks all for your replies, gathering all I was able to get the actual answer to my use case:
Without changing MyBaseClass and MyChildClass:
public class MyBaseClass
{
protected virtual bool MyMethod(int number)
{
return number == 1;
}
}
public class MyChildClass : MyBaseClass
{
public bool DoSomething(int number)
{
return MyMethod(number);
}
}
I was able to mock the protected method and save me a LOT of work and duplicate code (that was in MyBaseClassTests already)
[TestFixture]
public class MyChildClassTests
{
[Test]
public void Expected_Returns_False_WhenPassed_1()
{
var expected = false;
var myChildClass = new Mock<MyChildClass> {CallBase = true};
myChildClass.Protected().Setup<bool>("MyMethod", 1).Returns(expected);
var result = myChildClass.Object.DoSomething(1);
Assert.AreEqual(expected, result);
}
[Test]
public void Expected_Returns_True_WhenPassed_1()
{
var expected = true;
var myChildClass = new Mock<MyChildClass> {CallBase = true};
myChildClass.Protected().Setup<bool>("MyMethod", 1).Returns(expected);
var result = myChildClass.Object.DoSomething(1);
Assert.AreEqual(expected, result);
}
}
Thanks everyone for your help! :)
Related
I have the below code :
public interface Iinterface
{
Task<bool> RetrieveFromDataBase();
}
public class Class1 : Iinterface
{
public async Task<bool> RetrieveFromDataBase()
{
//do something
return true;
}
}
public class AnotherClass
{
Class1 c = new Class1();
public AnotherClass(Class1 obj)
{
c = obj;
}
public async Task<bool> ExecuteData()
{
var result = await c.RetrieveFromDataBase();
if (result)
{
//do some calculation
}
return true;
}
}
Now, I'm trying to write test cases for ExecuteData method. In this method I need to bypass RetrieveFromDataBase method. So I'm trying to mock it. This is the below code I have written.
[TestClass()]
public class AnotherClassTests
{
[TestMethod()]
public async Task ExecuteDataTest()
{
Task<bool> retValue = RetrieveFromDataBaseMoq(); // this returns true
var moq = new Mock<Iinterface>();
moq.Setup(x => x.RetrieveFromDataBase()).Returns(retValue);
AnotherClass obj = new AnotherClass((Class1)moq.Object); // error thrown from here
var result = await obj.ExecuteData();
Assert.IsTrue(result);
}
}
The mocking which is done is successful, i.e it doesn't throw any error. The problem I'm facing here is when I pass this mocked object a parameter to the constructor, it is throwing error System.InvalidCastException : Unable to cast object "Castle.Proxies.Iinterface" to type "Class1".
I know that it is not able to convert mocked interface to the concrete class type. But is there a way to rectify this error or pass the mocked object to the main class in anyway.
Many thanks!
you should declare variable c as an Iinterface. That's one of the advantages of using interfaces. You should dependend on the contract(interface) , instead of concrete implementations. Following that you are not coupled to concrete classes.
public class AnotherClass
{
Iinterface c; //I removed the default new since it will get assigned in constructor
public AnotherClass(Iinterface obj)
{
c = obj;
}
public async Task<bool> ExecuteData()
{
var result = await c.RetrieveFromDataBase();
if (result)
{
//do some calculation
}
return true;
}
}
The problem here I'm facing is, the class Class1 has some other methods and variables as well which are not declared in the interface.
You could do a composition inside Class1, and move the TInterface as a dependency inside Class1. Keep in mind that the interface is what you will get mocked in unit test
public class Class1
{
public TIinterface tinterface{get;private set;}
public Class1(TIinterface interface)
{
tinterface= interface;
}
}
public class YourCustomImplementation:TIinterface
{
public async Task<bool> RetrieveFromDataBase()
{
//do something
return true;
}
}
public class AnotherClass
{
Class1 c = new Class1();
public AnotherClass(Class1 obj)
{
c = obj;
}
public async Task<bool> ExecuteData()
{
var result = await c.tinterface.RetrieveFromDataBase();
if (result)
{
//do some calculation
}
return true;
}
}
I have an object that only initializes itself with barebones data when constructed (fast), and loads itself for real (slow) when first accessed. The idea is that I'm creating a lot of these barebones objects at startup and hash them into a map, then fully load each object whenever it is individually accessed for the first time. The problem is that I cannot guarantee how clients will interact with this object, there are multiple public methods that might be invoked.
Is there a good pattern to support this kind of situation? The obvious (and my current) solution is to track state with an internal bool, check against that bool in every function that might be invoked, and load that way. But that requires code duplication of that behavior across all public functions, and is vulnerable to errors.
I can imagine a single point-of-entry method that then dishes out behaviors based on a client request type etc., but before I go consider going down that road I want to see if there's a commonly accepted approach/pattern that I might not be aware of. I'm doing this in C#, but any insight is appreciated.
If I understood what you want to achieve, you are looking for the Proxy Design Pattern, more specifically, a virtual Proxy.
Refer to http://www.dofactory.com/net/proxy-design-pattern
A small example would be something like:
public abstract class IObjectProvider
{
public abstract IObjectProvider Object{get;}
public abstract void doStuff();
}
public class RealObject : IObjectProvider
{
public RealObject()
{
//Do very complicated and time taking stuff;
}
public override IObjectProvider Object
{
get { return this; }
}
public override void doStuff()
{
//do this stuff that these objects normally do
}
}
public class ObjectProxy : IObjectProvider
{
private IObjectProvider objectInstance = null;
public override IObjectProvider Object
{
get
{
if (objectInstance == null)
objectInstance = new RealObject();
return objectInstance;
}
}
public override void doStuff()
{
if(objectInstance!=null)
objectInstance.doStuff();
}
}
public class SkeletonClass
{
public IObjectProvider Proxy1 = new ObjectProxy();
public IObjectProvider Proxy2 = new ObjectProxy();
}
static void Main(String[] args)
{
//Objects Not Loaded
SkeletonClass skeleton = new SkeletonClass();
//Proxy1 loads object1 on demand
skeleton.Proxy1.Object.doStuff();
//Proxy2 not loaded object2 until someone needs it
}
Here's an example of dynamic proxy approach.
using System;
using System.Diagnostics;
using Castle.DynamicProxy; //Remember to include a reference, too. It's nugettable package is Castle.Core
namespace ConsoleApp
{
public class ActualClass
{
//Have static instances of two below for performance
private static ProxyGenerator pg = new ProxyGenerator();
private static ActualClassInterceptor interceptor = new ActualClassInterceptor();
//This is how we get ActualClass items that are wrapped in the Dynamic Proxy
public static ActualClass getActualClassInstance()
{
ActualClass instance = new ActualClass();
return pg.CreateClassProxyWithTarget<ActualClass>(instance, interceptor);
}
//Tracking whether init has been called
private bool initialized = false;
//Will be used as evidence of true initialization, i.e. no longer null
private int? someValue = null;
public void Initialize()
{
if (!initialized)
{
//do some initialization here.
someValue = -1; //Will only get set to non-null if we've run this line.
initialized = true;
}
}
//Any methods you want to intercept need to be virtual!
public virtual int replaceValue(int value)
{
//below will blow up, if someValue has not been set to -1 via Initialize();
int oldValue = someValue.Value;
someValue = value;
return oldValue;
}
//block off constructor from public to enforce use of getActualClassInstance
protected ActualClass() { }
}
public class ActualClassInterceptor : ActualClass, IInterceptor
{
public void Intercept(IInvocation invocation)
{
//Call initialize before proceeding to call the intercepted method
//Worth noting that this is the only place we actually call Initialize()
((ActualClass)invocation.InvocationTarget).Initialize();
invocation.Proceed();
}
}
class Program
{
static void Main(string[] args)
{
ActualClass instance1 = ActualClass.getActualClassInstance();
ActualClass instance2 = ActualClass.getActualClassInstance();
int x1 = instance1.replaceValue(41);
int x2 = instance2.replaceValue(42);
int y1 = instance1.replaceValue(82);
Debug.Assert(y1 == 41);
int y2 = instance2.replaceValue(84);
Debug.Assert(y2 == 42);
var read = Console.ReadKey();
}
}
}
Is there a way to force the override of a virtual method if another method is overriden?
public class BaseClass
{
protected virtual void A()
{
// a default action called first
}
protected virtual void B()
{
// a default action called second that,
// if A was overriden, makes no sense
}
}
EDIT
Thanks a lot for the Answers. It's very interresting to see how this could be achieved, but for my explicit case it's not critically important.
Also, i forgot to mention how those Methods would be used: (in BaseClass)
pulbic bool EditEntity(Guid id)
{
A();
// Some code that edits Entites
B();
}
No, you cannot. But this makes me think how could you achieve the same concept?
The best idea I came up with was declaring an interface which had the package of methods to override.
public interface IMyOverridablePackage
{
void A_Override();
void B_Override();
}
Then give the base class a protected method where the child class can explicitly override the set of methods.
protected void SetOverride(IMyOverridablePackage overridablePackage)
{
_overridablePackage = overridablePackage;
}
So then here's two classes, one which does and one which does not override the set of methods:
public class NotOverriding : MyBaseClass
{
}
public sealed class Overriding : MyBaseClass, IMyOverridablePackage
{
public Overriding()
{
SetOverride(this);
}
void IMyOverridablePackage.A_Override()
{
Console.WriteLine("Overriding.A_Override");
}
void IMyOverridablePackage.B_Override()
{
Console.WriteLine("Overriding.B_Override");
}
}
And the implementation of the base class:
public abstract class MyBaseClass
{
private IMyOverridablePackage _overridablePackage;
public void A()
{
_overridablePackage.A_Override();
}
public void B()
{
_overridablePackage.B_Override();
}
private class MyDefaultPackage : IMyOverridablePackage
{
private readonly MyBaseClass _myBaseClass;
internal MyDefaultPackage(MyBaseClass myBaseClass)
{
_myBaseClass = myBaseClass;
}
void IMyOverridablePackage.A_Override()
{
_myBaseClass.A_Impl();
}
void IMyOverridablePackage.B_Override()
{
_myBaseClass.B_Impl();
}
}
protected MyBaseClass()
{
_overridablePackage = new MyDefaultPackage(this);
}
private void A_Impl()
{
Console.WriteLine("MyBaseClass.A_Impl");
}
private void B_Impl()
{
Console.WriteLine("MyBaseClass.B_Impl");
}
protected void SetOverride(IMyOverridablePackage overridablePackage)
{
_overridablePackage = overridablePackage;
}
}
This does achieve the goal, but of course you have to ask 'how much to I want it?' Is it worth the extra code?
Here's a working dotnetfiddle: https://dotnetfiddle.net/xmPn20
Maybe you cannot force it via compiler errors, but you could write a test which asserts that the methods are in sync via some attributes. It would also be visible that there is some dependency.
A crude example would be something like this:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class VersionAttribute : Attribute
{
public VersionAttribute(string version)
{
Version = version;
}
public string Version { get; set; }
}
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class DependentAttribute : Attribute
{
public string DependentOnMethod { get; set; }
public string DependentOnVersion { get; set; }
}
[Dependent(DependentOnMethod = "OtherMethod", DependentOnVersion = "1")]
public static void FirstMethod()
{
}
[Version("1")]
public static void OtherMethod()
{
}
And the test that asserts the version numbers:
[Test]
public void TestVersions()
{
foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
{
foreach (var method in type.GetMethods())
{
foreach (var customAttribute in method.GetCustomAttributes())
{
var dependent = customAttribute as DependentAttribute;
if (dependent != null)
{
var methodInfo = type.GetMethod(dependent.DependentOnMethod);
Assert.That(methodInfo, Is.Not.Null, "Dependent method not found");
VersionAttribute version = methodInfo.GetCustomAttributes().OfType<VersionAttribute>().FirstOrDefault();
Assert.That(version, Is.Not.Null, "No version attribute on dependent method");
Assert.That(dependent.DependentOnVersion, Is.EqualTo(version.Version));
}
}
}
}
}
thus, if you update one of your methods you would need to update the version number of either the Version attribute or the Dependent attribute. Hopefully better than nothing.
You may change your design :
public abstract class BaseClass
{
protected abstract void A();
}
public class BaseClassEx
{
protected sealed override void A()
{
// action Calling B
}
protected virtual void B()
{
// a default action called second
}
}
In the case of Equals (actually both Equals overloads, concrete type and object) and GetHashCode, Resharper includes a rule that shows a warning in its IntelliSense whenever you forget to implement one of these.
You could enforce it in your code with a runtime check in the constructor of the base class:
public class Base
{
public Base()
{
var baseA = typeof (Base).GetRuntimeMethod("MethodA", new Type[0]);
var baseB = typeof (Base).GetRuntimeMethod("MethodB", new Type[0]);
var derivedA = GetType().GetRuntimeMethod("MethodA", new Type[0]);
var derivedB = GetType().GetRuntimeMethod("MethodB", new Type[0]);
if (baseA.DeclaringType == derivedA.DeclaringType ^
baseB.DeclaringType == derivedB.DeclaringType)
throw new InvalidOperationException("You must override MethodA and MethodB together.");
}
public virtual string MethodA() { return "Hello"; }
public virtual int MethodB() { return 123; }
}
In the following example, I want to test the TestMe.DoSomething() function.
I want to mock the ISomething interface that is used within this method and make it return different values (depending on the specific unit test.)
In real life the ISomething interface winds up calling out to expensive 3rd party resources -- I definitely don't want to just call a real ISomething.
Here is the example structure:
class TestMe
{
public void DoSomething()
{
ISomething s = SomethingFactory();
int i = s.Run();
//do things with i that I want to test
}
private ISomething SomethingFactory()
{
return new Something();
}
}
interface ISomething
{
int Run();
}
class Something : ISomething
{
public int Run()
{
return 1;
}
}
Here is code that doesn't work:
var fakeSomething = new Mock<ISomething>();
var testMe = new TestMe();
Mock.Get(testMe).Setup(p => p.SomethingFactory()).Returns(fakeSomething.Object);
testMe.DoSomething();
Because SomethingFactory() is private, I cannot set the return value from that method to be what I want.
Any advice on how I can solve this?
Make the factory a full interface / class and remove the SomethingFactory method from TestMe.
public interface ISomethingFactory {
ISomething MakeSomething();
}
public sealed class SomethingFactory {
public ISomething MakeSomething() {
return new Something();
}
}
class TestMe
{
private readonly ISomethingFactory _somethingFactory;
public TestMe(ISomethingFactory somethingFactory) {
_somethingFactory = somethingFactory;
}
public void DoSomething()
{
ISomething s = _somethingFactory.MakeSomething();
int i = s.Run();
//do things with i that I want to test
}
}
This will allow you to mock ISomethingFactory to return a mock of ISomething.
While I think you may protest this solution as too drastic a change, I think its better than making a class that's not sealed with a members who's only reason for being virtual is for testing.
You can inject your dependency. If you don't want to break all your callers you can add two constructors and use the one that lets you inject fake in tests
class TestMe
{
private readonly ISomething something;
TestMe() : this(new RealSomething()
{
}
TestMe(ISomething sth)
{
something = sth;
}
public void DoSomething()
{
ISomething s = SomethingFactory();
int i = s.Run();
//do things with i that I want to test
}
private ISomething SomethingFactory()
{
return new Something();
}
}
Second way would be to change the
SomethingFactory
method to protected virtual and override it in derived class and use that class instead, or to setup
class TestableTestMe : TestMe
{
private readonly ISomething something;
TestableTestMe(ISomething testSpecific)
{
something = testSpecific;
}
public void DoSomething()
{
ISomething s = SomethingFactory();
int i = s.Run();
//do things with i that I want to test
}
protected override ISomething SomethingFactory()
{
return something;
}
}
This technique is called "extract and override"
Changing SomethingFactory() to be protected virtual allows you to use Moq.Protected to access the method by its name:
public class TestMe
{
public void DoSomething()
{
ISomething s = SomethingFactory();
int i = s.Run();
//do things with i that I want to test
}
protected virtual ISomething SomethingFactory()
{
return new Something();
}
}
public interface ISomething
{
int Run();
}
public class Something : ISomething
{
public int Run()
{
return 1;
}
}
So you can run this test:
var fakeSomething = new Mock<ISomething>();
fakeSomething.Setup(p => p.Run()).Returns(2);
var testMe = new Mock<TestMe>();
testMe.Protected().Setup<ISomething>("SomethingFactory").Returns(fakeSomething.Object);
testMe.Object.DoSomething();
I've have searched on this and it seems to be a catch all, unfortunately everything I've read doesn't help figure it out. Here is the class:
public interface IMockInterface
{
MockClass MockedMethod();
MockClass MockThis();
}
public class MockClass : IMockInterface
{
public virtual MockClass MockedMethod()
{
MockClass returnValue;
returnValue = new MockClass();
returnValue.SomeMessage = "Not mocked";
return returnValue;
}
public MockClass MockThis()
{
MockClass mock;
MockClass returnValue;
mock = new MockClass();
return mock.MockedMethod();
}
}
And the test:
public void MockTest_Internal()
{
MockClass mainClass;
MockClass returnedClass;
IMockInterface mockProvider;
mainClass = new MockClass();
mockProvider = repository.StrictMock<IMockInterface>();
Expect.Call(mockProvider.MockedMethod())
.Return(new MockClass { SomeMessage = "Mocked" });
repository.ReplayAll();
returnedClass = mainClass.MockThis();
provider.AssertWasCalled(item => item.MockedMethod());
Assert.IsTrue(returnedClass.SomeMessage == "Mocked");
}
And have also tried and doesn't work
But I keep getting this exception:
Rhino.Mocks.Exceptions.ExpectationViolationException:
IMockInterface.MockedMethod(); Expected #1, Actual #0
Now from what I've read this would suggest either the method was called with different than expected parameters OR the method was never called but was expected to be called. This isn't the case for the test.
Side Note: This is my first time really using Rhino.Mocks without some in house code so I am basically picking it up as I go. There could be something really stupid here...
This was the old test commented on, but is not what I should have been using:
public void MockTest_Internal()
{
MockClass mainClass;
MockClass returnedClass;
IMockInterface mockProvider;
mainClass = new MockClass();
var provider = MockRepository.GenerateStub<IMockInterface>();
provider.Stub(item => item.MockedMethod())
.Return(new MockClass { SomeMessage = "Mocked" });
returnedClass = mainClass.MockThis();
provider.AssertWasCalled(item => item.MockedMethod());
Assert.IsTrue(returnedClass.SomeMessage == "Mocked");
}
You're telling the mock framework to stub the MockedMethod class on the provider object, but you never inject the provider into the mainClass object to be used. It's not clear to me what you are trying to accomplish but if you want the mocked method to be called then it has to be called on the object on which the stub was set up.
If you define MockThis as below, I think you will find that it will work.
public MockClass MockThis(IMockInterface provider)
{
return provider.MockMethod();
}
The bottom line is that you get the exception because the method was never called on the provider, only on the mainClass object.
EDIT: Example
public class ClassUnderTest
{
private ProviderClass provider { get; set; }
public ClassUnderTest( ProviderClass provider )
{
this.Provider = provider;
}
public int DoOperation()
{
return this.Provider.ProviderOperation();
}
}
public class ProviderClass
{
private int value = 42;
public ProviderClass()
{
}
public virtual int ProviderOperation()
{
return this.value;
}
}
[TestMethod]
public void DoOperationTest()
{
ProviderClass mockProvider = MockRepository.GenerateMock<ProviderClass>();
mockProvider.Expect( mp => mp.ProviderOperation() ).Return( -1 );
ClassUnderTest target = new ClassUnderTest( mockProvider );
int expectedValue = -1;
int value = target.DoOperation();
Assert.AreEqual( expectedValue, value );
mockProvider.VerifyAllExpectations();
}
Normally the ProviderClass object would return 42 from the ProviderOperation method, but we've mocked it out and told it to return -1. When the ClassUnderTest DoOperation method is called, the mock provider object's ProviderOperation method is invoked and returns the mocked value of -1.
Hope this helps.
I usually get this error when a stubbed method is called with an object argument that I build in the test and in the tested code the object is built before calling that method. The solution is to use the Rhino.Mocks Matches().
Ex:
Arg<string>.Matches(s => s.Contains("some substring"))