Do I Stub or Shim a method inside my test method? - c#

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!

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
}

Why does my breakpoint never get hit, when using AutoMock.GetLoose()?

Consider the following simple test:
[Fact]
public void Should_Test_Something()
{
using (var mock = AutoMock.GetLoose())
{
using (var workflow = mock.Create<IWorkflow>())
{
var result = workflow.DoSomething();
// ...
}
}
}
When setting a breakpoint inside of DoSomething() Visual Studio will never break upon it. Why is that? I can step through the test without any issues.
public interface IWorkflow
{
bool DoSomething();
}
public class Workflow : IWorkflow
{
public Workflow( // Some long list of dependencies...)
public bool DoSomething()
{
// I do something, a breakpoint set here does never get hit
}
}
When setting a breakpoint inside of DoSomething() Visual Studio will never break upon it. Why is that? I can step through the test without any issues.
Because the interface is being mock and used. not the actual class implementation.
That is the whole point of mocking the interface to begin with. So that the actual class is not used. But rather the mock of the interface.
how can I test my method DoSomething() in an isolated way, without having to supply all the dependencies?
You will need to mock all the dependencies and initialize the actual class with those dependencies.
[Fact]
public void Should_Test_Something() {
using (var mock = AutoMock.GetLoose()) {
//Arrange
IWorkflow workflow = mock.Create<Workflow>(); //<-- note asking for actual class
//Act
var result = workflow.DoSomething();
//Assert
// ...assert expected behavior
}
}
Provided all the dependencies can be created with out undesirable behavior the auto mock with create mocks of the dependencies and pass that to the class.

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

MS Fakes - Access base class members of stub

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.

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