MS Fakes - Access base class members of stub - c#

Is it possible to mock out the members of a base class in a stub? For example, if I have:
public class MyObjectBase {
public virtual int GetNumber() {
return 1;
}
}
public class MyObject : MyObjectBase {
}
Then I want to be able to write a test that does this:
void MyTest() {
var stub = new StubMyObject();
stub.GetNumber01 = () => 2; // this line won't compile
Assert.Equal(2, stub.GetNumber());
}
But, GetNumber01 doesn't exist on StubMyObject because it's a member of the base class.
EDIT:
After removing the fakes assembly and re-adding it, this problem goes away. Looks like it was just a problem with the fakes assembly not getting updated.

Related

Use inheritance in MSTest for shared tests

I'm trying to write Unittests for D365 Plugins and CodeActivities (both being classes). There are small tests that should run in every plugin, such as:
[TestMethod]
public void NullLocalPluginContext()
{
XrmFakedContext context = new XrmFakedContext();
Assert.ThrowsException<InvalidPluginExecutionException>(
() => context.ExecutePluginWith<SomePlugin>(null));
}
Where SomePlugin is the class to be tested (which is for each child different) and cannot be abstract (awaits IPlugin). For example here it's a CheckDuplicateOrder in the child:
[TestClass]
public class CheckDuplicateOrderTest
{
[TestMethod]
public void NullLocalPluginContext()
{
XrmFakedContext context = new XrmFakedContext();
Assert.ThrowsException<Exception>(
() => context.ExecutePluginWith<CheckDuplicateOrder>(null));
}
}
For these small tests I'd like to have this parent with Shared tests but I don't know how to reference the 'to-be' child's target.
I prefer MSTest, but any NuGet framework is accepted.
Maybe this helps with understanding
Every plugin would have it's own test class.
Every plugintest class needs the basic.
These basic tests should be inherited from parent (so they don't take up space).
Plugins: Dog, Cat, Mouse
PluginTests: DogTest, CatTest, MouseTest
BasePluginTest -> should have shared tests where SomePlugin in the exmaple is Dog/Cat/Mouse. But I don't know how to reference it. Every plugin would have a function TestWalk() { .. ExecutePluginWith<SomePlugin>}. The Cat should call CatTest, the Dog should call DogTest.
As with a normal class you should favour composition over inheritance. Even
though test-classes do not have to follow the same rules and guidelines as normal classes doesn't mean we cannot implement them.
So when you feel you have some common functionality accross your test-classes you should extract some class that is used by your tests. You would do the same for a normal business-class also, won´t you?
class CommonFunc
{
public static bool NullLocalPluginContext<T, TException>() where T: IPlugIn, TException : Exception
{
XrmFakedContext context = new XrmFakedContext();
try { context.ExecutePluginWith<T>(null)) };
catch (T e) { return true; }
return false;
}
}
[TestClass]
public class CheckDuplicateOrderTests
{
[TestMethod]
public void NullLocalPluginContext()
{
Assert.IsTrue(CommonFunc.NullLocalPluginContext<CheckDuplicateOrder, Exception>(null));
}
}
[TestClass]
public class SomeOtherPluginTests
{
[TestMethod]
public void NullLocalPluginContext()
{
Assert.IsTrue(CommonFunc.NullLocalPluginContext<SomePlugin, InvalidPluginExecutionException>(null));
}
}
You could also make your common method rethrow the exception instead of just returning true or false if you want to log the actual exception being thrown within the test-framework.
Disclaimer: some people won't like this because it abuses class inheritance to save code. It's a potential tool for the job, you can evaluate whether it works for you or not.
This seems like it could be achievable with a base class to define the shared tests. Maybe something like this would achieve what you're trying to do?
// note: no [TestClass] on this type so it doesn't get discovered by MSTest.
// Probably should also be abstract.
public class SharedTests<T> where T : IPlugin
{
[TestMethod]
public void NullLocalPluginContext()
{
XrmFakedContext context = new XrmFakedContext();
Assert.ThrowsException<Exception>(
() => context.ExecutePluginWith<T>(null));
}
}
Your plugin classes would inherit from this class:
[TestClass]
public class CheckDuplicateOrderTests : SharedTests<CheckDuplicateOrder>
{
// NullLocalPluginContext test is inherited from the parent type
}
[TestClass]
public class SomeOtherPluginTests : SharedTests<SomeOtherPlugin>
{
// Also has NullLocalPluginContext test inherited, but for testing SomeOtherPlugin
}

how to skip constructor call from unit test?

I am executing unit test for one of class method "Execute", but don't want to execute class constructor code.
Is there any way to skip constructor code call from the unit test execution?
Class Code,
public class DemoCls
{
public DemoCls()
{
string ConfigFolderPath = Path.Combine(Environment.CurrentDirectory, #"\Config");
//string dataFolder = #"C:\Data1";
foreach (string X in Directory.EnumerateFiles(ConfigFolderPath, "test" + "*.xml"))
{
}
}
public void Execute()
{
}
}
Unit Test Code,
[TestClass()]
public class DemoClsTests
{
[TestMethod()]
public void ExecuteTest()
{
var X = new DemoCls();
X.Execute();
}
}
Rewrite the class, one of two ways:
Pass the information into the constructor using an interface (which can be mocked in unit-tests)
public interface IConfigFiles
{
List<string> Files { get; set; }
}
public DemoCls(IConfigFiles files)
{
}
Remove configuration code from the constructor, and put it in a different function instead.
public DemoCls()
{
// does nothing
}
public void Setup()
{
string ConfigFolderPath = Path.Combine(Environment.CurrentDirectory, #"\Config");
//...
}
Interfaces are better for unit-testing.
"Is there any way to skip constructor code call from the unit test execution?"
The answer is: No (for instance methods)
You can use a unit testing frameworks that allows you to mock concrete classes in order to fake a class without an interface, for example i'm using Typemock Isolator and with that i can mock almost any class and decide what is happening with all the class's members and its constructor.
here is a test for the class that you had in your question:
[TestMethod,Isolated]
public void TestMethod()
{
var fake = Isolate.Fake.Instance<DemoCls>(Members.CallOriginal, ConstructorWillBe.Ignored);
fake.Execute();
Isolate.Verify.WasCalledWithAnyArguments(() => fake.Execute());
}
You could wrap you ctor code in the "if" preprocessor directive and execute it conditionally, only during a non-test run.
#define DEBUG
// ...
#if DEBUG
Console.WriteLine("Debug version");
#endif
See
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives/preprocessor-if

Ordering of Postsharp Aspects execution

Ok, this may get lengthy. I am trying to do two things:
I want to have a class that implements an interface by holding an instance of another class that every call is routed to.
I also want to intercept all method calls and do something.
Doing both on their own works great. Combining them seems to work only in one execution order and as Murphy has it, it's the wrong one (at least for me).
I'd like to inject the composition first so that the interception of all calls will also intercept those that were previously injected.
namespace ConsoleApplication13
{
using System;
using System.Reflection;
using PostSharp;
using PostSharp.Aspects;
using PostSharp.Aspects.Dependencies;
using PostSharp.Extensibility;
[Serializable]
[ProvideAspectRole("COMPOSER")]
public sealed class ComposeAspectAttribute : CompositionAspect
{
[NonSerialized]
private readonly Type interfaceType;
private readonly Type implementationType;
public ComposeAspectAttribute(Type interfaceType, Type implementationType)
{
this.interfaceType = interfaceType;
this.implementationType = implementationType;
}
// Invoked at build time. We return the interface we want to implement.
protected override Type[] GetPublicInterfaces(Type targetType)
{
return new[] { this.interfaceType };
}
// Invoked at run time.
public override object CreateImplementationObject(AdviceArgs args)
{
return Activator.CreateInstance(this.implementationType);
}
}
[Serializable]
[ProvideAspectRole("INTERCEPTOR")]
[MulticastAttributeUsage(MulticastTargets.Method)]
[AspectRoleDependency(AspectDependencyAction.Order, AspectDependencyPosition.After, "COMPOSER")]
public sealed class InterceptAspectAttribute : MethodInterceptionAspect
{
public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo)
{
base.CompileTimeInitialize(method, aspectInfo);
// Warning in VS output
Message.Write(method, SeverityType.Warning, "XXX", "Method: " + method.Name);
}
public override void OnInvoke(MethodInterceptionArgs args)
{
Console.WriteLine("Intercepted before");
args.Proceed();
Console.WriteLine("Intercepted after");
}
}
interface ITest
{
void Call();
}
class TestImpl : ITest
{
public void Call()
{
Console.WriteLine("CALL remote implemented");
}
}
[InterceptAspect(AspectPriority = 1)]
[ComposeAspect(typeof(ITest), typeof(TestImpl), AspectPriority = 2)]
class Test
{
// this should, after compilation, have all methods of ITest, implemented through an instance of TestImpl, which get intercepted before TestImpl is called
public void CallLocalImplementedTest()
{
Console.WriteLine("CALL local implemented");
}
}
class Program
{
static void Main()
{
var test = new Test();
ITest t = Post.Cast<Test, ITest>(test);
Console.WriteLine("TEST #1");
t.Call();
Console.WriteLine("TEST #2");
test.CallLocalImplementedTest();
Console.ReadLine();
}
}
}
I have tried to influence the execution order of the two aspects by
AspectRoleDependency, making the interceptor depend on the composer to run first
AspectPriority, also making the composer run first.
As the tests always yield
TEST #1
CALL remote implemented
TEST #2
Intercepted before
CALL local implemented
Intercepted after
it obviously doesn't work. Do you have a clue why my execution order has not changed? Did I do something wrong, did I miss a detail in the documentation? What can I do to intercept my composition-injected methods as well?
With the current aspects and your current setup you cannot achive your desired result.
The problem is in how Postsharp work: it does the IL waving in one step and it only applies the InterceptAspect to the methods which are present at original compile time so it does not see the new interface implementations added with the ComposeAspect.
So no ordering of the accepts or providing roles, priorities or other configuration would help here.
One workaround would be to add the InterceptAspect on the injected TestImpl class:
[InterceptAspect]
class TestImpl : ITest
{
public void Call()
{
Console.WriteLine("CALL remote implemented");
}
}
In this case the logging logic will be added directly TestImpl so these method will contain the logging when it will be composed into your Test class.
Or if you don't mark every implementation you can put your aspect on the interface itself with:
[InterceptAspect(AttributeInheritance = MulticastInheritance.Multicast)]
interface ITest
{
void Call();
}

Do I Stub or Shim a method inside my test method?

I have a method base.ResolveDate() inside my test method that's coming from a base class and its public and virtual. I want to stub/shim this method with my own, so do I stub or shim? Stub or Shim, how would I go about doing it? From my experience with MS Fakes it seems like it would be a Stub because Stub can only influence overridable methods. - ALM 2012
Here is the test method:
public override DateTime ResolveDate(ISeries comparisonSeries, DateTime targetDate)
{
if (comparisonSeries == null)
{
throw new ArgumentNullException("comparisonSeries");
}
switch (comparisonSeries.Key)
{
case SeriesKey.SomeKey1:
case SeriesKey.SomeKey2:
case SeriesKey.SomeKey3:
case SeriesKey.SomeKey4:
case SeriesKey.SomeKey5:
return DateHelper.PreviousOrCurrentQuarterEnd(targetDate);
}
return base.ResolveDate(comparisonSeries, targetDate);
}
Here is the method from the base class I want to Stub/Shim?
public virtual DateTime ResolveDate(ISeries comparisonSeries, DateTime targetDate)
{
if (this.key == comparisonSeries.Key)
return targetDate;
return DateHelper.FindNearestDate(targetDate, comparisonSeries.AsOfDates);
}
To test a derived method in isolation from its base implementation, you need to shim it. Given the following system under test:
namespace ClassLibrary7
{
public class Parent
{
public virtual string Method()
{
return "Parent";
}
}
public class Child : Parent
{
public override string Method()
{
return base.Method() + "Child";
}
}
}
You can write the following test for the Child.Method().
using ClassLibrary7;
using ClassLibrary7.Fakes;
using Microsoft.QualityTools.Testing.Fakes;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Test
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
using (ShimsContext.Create())
{
var child = new Child();
var shim = new ShimParent(child);
shim.Method = () => "Detour";
string result = child.Method();
Assert.IsFalse(result.Contains("Parent"));
Assert.IsTrue(result.Contains("Detour"));
Assert.IsTrue(result.Contains("Child"));
}
}
}
}
Note that the first two Asserts are included only to illustrate how the parent method is detoured. In a real test only asserts for the child method would be needed.
1) First add a reference to the actual dll you want to test example: ABC.Interfaces
2) Then expand your references and on the actual dll that should now be in your references right click and say "Add Fakes Assembly"
Visual studio will process the references and if it was successfull you should see a new reference called ABC.Interfaces.1.0.0.0.Fakes..
You will now be able to see the stub and shims been added to your methods.
Hope this helps!

How to test virtual methods using Moles?

How can I test the IsHappy function using Moles?
class SomeClass
{
protected virtual bool IsHappy(string mood)
{
return (mood == "Happy");
}
}
I tried to test if by using Stub:
SSomeClass stub = new SSomeClass();
stub.CallBase = true;
Assert.IsTrue(stub.IsHappyString("Happy"));
... but the IsHappyString method returns null thus throwing a NullReference exception.
So, how can I test the default implementation of IsHappy method?
I'd forget about stubs here. Stubs/mocks are for when you want to fake the behavior of a dependency. You'd stub your SomeClass if had SomeClassClient that you wanted to test and it used SomeClass:
public class Foo
{
public virtual int GetFoosInt()
{
return 12;
}
}
public class FooClient
{
private Foo _foo;
public FooClient(Foo foo)
{
_foo = foo;
}
public int AddOneToFoosInt()
{
return _foo.GetFoosInt() + 1;
}
}
In this example, when testing FooClient, what you want to test is that it returns one more than "GetFoosInt()". You don't actually care what FoosInt is for testing the FooClient. So, you create a Foo stub where you can setup GetFoosInt to return whatever you want.
In your case, testing a protected virtual member, I'd go with this:
[TestClass]
public class SomeClassTest
{
private class DummySomeClass : SomeClass
{
public bool IsHappyWrapper(string mood)
{
return IsHappy(mood);
}
}
[TestMethod]
public void SomeTest()
{
var myClass = new DummySomeClass();
Assert.IsTrue(myClass.IsHappyWrapper("Happy"));
}
}
This gives you 'direct' access to the protected virtual to test default behavior. Only word of caution is that if you start defining abstract members and adding to SomeClass in general, you'll have to add them to this dummy inheritor as well, adding to testing maintenance overhead.
The purist in me says that you should leave protected members alone and only test them through the public interface. But, that may or may not be practical in your situation, and I don't really see any harm in this approach.
Stubs and Moles are for isolating a class from any dependencies it has, either environmental dependencies or class dependencies. This class has no dependencies whatsoever, so why are you trying to mole or stub it?
If you want to make sure this base class works properly when people override it, then you'll need to create a test implementation. In that case this is more or less what your test cases should look like:
public SomeClassTestAdapter : SomeClass
{
public bool GetIsHappy(string mood)
{
return IsHappy(mood);
}
}
[Test]
public void ShouldReturnTrueWhenPassedHappy()
{
var classUnderTest = new SomeClassTestAdapter();
bool result = classUnderTest.IsHappy("Happy");
Assert.IsTrue(result, "Expected result to be true");
}
[Test]
public void ShouldReturnFalseWhenPassedLowerCaseHappy()
{
var classUnderTest = new SomeClassTestAdapter();
bool result = classUnderTest.IsHappy("happy");
Assert.IsFalse(result, "Expected result to be false");
}
[Test]
public void ShouldReturnFalseWhenPassedNull()
{
var classUnderTest = new SomeClassTestAdapter();
bool result = classUnderTest.IsHappy(null);
Assert.IsFalse(result, "Expected result to be false");
}
Etc.
There is no place in this code that stubs or moles should be squeezed in.
If you don't want to create an adapter class for this case, you can use built-in .Net features rather than a big, paid dependency like Moles. Reflections and dynamic let you get access to protected or private members. See this example:
http://igoro.com/archive/use-c-dynamic-typing-to-conveniently-access-internals-of-an-object/

Categories

Resources