I want to do mock extension method, but it does not work. How can this be done?
public static class RandomExtensions
{
public static IEnumerable<int> NextInt32s(this System.Random random, int neededValuesNumber, int minInclusive, int maxExclusive)
{
// ...
}
}
[Fact]
public void Select()
{
var randomizer = Substitute.For<DefaultRandom>();
randomizer.NextInt32s(3, 1, 10).Returns(new int[] { 1, 2, 3 });
}
NSubstitute can not mock extension methods as per Sriram's comment, but you can still pass a mocked argument to an extension method.
In this case, the Random class has virtual methods, so we can mock that directly with NSubstitute and other DynamicProxy-based mocking tools. (For NSubstitute in particular we need to be very careful mocking classes. Please read the warning in the documentation.)
public static class RandomExtensions {
public static IEnumerable<int> NextInt32s(this System.Random random, int neededValuesNumber, int minInclusive, int maxExclusive) { /* ... */ }
}
public class RandomExtensionsTests {
[Test]
public void Select()
{
const int min = 0, max = 10;
var randomizer = Substitute.For<Random>();
randomizer.Next(min, max).Returns(1, 2, 3);
var result = randomizer.NextInt32s(3, 0, 10).ToArray();
Assert.AreEqual(new[] {1, 2, 3}, result);
}
}
Yes you can mock if you create an interface such as IRandom and extend the interface instead of the actual implementation. Then you should be able mock the interface in your test class.
public interface IRandom
{
}
public class Random : IRandom
{
}
public static class RandomExtensions
{
public static string NextInt32s(
this IRandom random,
int neededValuesNumber,
int minInclusive,
int maxExclusive)
{
}
}
In your test class add:
IRandom randomizer = Substitute.For<IRandom>();
var result = randomizer.NextInt32s(3,0,10);
By this process you are just mocking the interface not the actual class.
As an extension to other answers, here is how I got round it.
Imagine there is an interface IDoStuff and there is a library that extends IDoStuff. You have a class MyClass that implements IDoStuff and somewhere someone uses the extension method against the interface. It looks like this;
using System;
interface IDoStuff
{
string SayHello();
}
class MyClass : IDoStuff
{
public string SayHello()
{
return "Hello";
}
}
// somewhere someone wrote an extension method for IDoStuff
static class DoStuffExtensions
{
static string SayHelloToBob(this IDoStuff other)
{
return other.SayHello() + " Bob";
}
}
class UserOfIDoStuff
{
void UseIDoStuff(IDoStuff incoming)
{
Console.WriteLine(incoming.SayHelloToBob());
}
}
You want to mock IDoStuff but you cannot mock the extension method SayHelloToBob. What you can do is to create another interface that implements IDoStuff but also includes SayHelloToBob.
interface IDoStuffWithExtensions : IDoStuff
{
string SayHelloToBob();
}
class MyClass : IDoStuffWithExtensions
{
public string SayHello()
{
return "Hello";
}
// Wrap / internalise the extension method
public string SayHelloToBob()
{
return DoStuffExtensions.SayHelloToBob(this);
}
}
class UserOfIDoStuff
{
void UseIDoStuff(IDoStuffWithExtensions incoming)
{
Console.WriteLine(incoming.SayHelloToBob());
}
}
Now you can happily mock IDoStuffWithExtensions.
According to SOLID principle dependence inversion defines that lower level model should not be depended high level model but depended on abstract like interface and mocking concept is mainly used to mock interface so that low level model is not tested.
Related
I am looking for the best way to test an abstract class with constructor parameters. It is important to me that I can also include members that are marked as protected. Here is what I came up with. Let's take the following class as an example:
public abstract class MyAbstractClass {
public MyAbstractClass(string someParam) { ... }
protected int MethodToTest(int param1, int param2) { ... }
}
One possibility would be to derive the TestFixture directly from the abstract class and thus gain access to the members that are marked as protected. But what I rather don't like about it is that I have to pass the constructor parameter in the TestFixture attribute. Furthermore, I have introduced a magic string in addition to this (admittedly, I could still put it into a constant).
[TestFixture("constructor param here")]
public class MyTestFixture : MyAbstractClass {
public MyTestFixture(string someParam) { ... }
[Test]
public void ConstructorTest() {
Assert.Throws<ArgumentNullException>(() => _ = new MyTestFixture(null!));
}
[Test]
public void MethodTest() {
Assert.That(this.MethodToTest(1, 2), Is.EqualTo(3));
}
}
Another way might be to simply build a class (in the unit test project) around the abstract class and pass the protected member through. Somehow that doesn't seem very practical to me either. Above all, it bloats the file containing the test terribly as soon as the classes get bigger.
[TestFixture]
public class MyTestFixture {
private class MyAbstractClassWrapper : MyAbstractClass {
public MyAbstractClassWrapper(string someParam) : base(someParam) { }
public new int MethodToTest(int param1, int param2) => base.MethodToTest(param1, param2);
}
[Test]
public void ConstructorTest() {
Assert.Throws<ArgumentNullException>(() => _ = new MyAbstractClassWrapper(null!));
}
[Test]
public void MethodTest() {
MyAbstractClassWrapper sut = new("constructor param");
Assert.That(sut.MethodToTest(1, 2), Is.EqualTo(3));
}
}
What do you guys think? Are there any better solutions or do I have to settle with my approaches above?
I'm using Xunit and Moq for unit testing. So far I was able to succesfully mock and test methods from interfaces.
But how am I supposed to mock and test the methods of a class that I have no control over. The class has no interface and the methods are not virtual.
I looked into Type Mock Isolator, but I could not make that work, and also that is not a feasible solution because it's paid and only has a 14 day trial, and I need to do this long term.
What are my options?
Create a wrapper for the dependency. You don't need to test the implementation of code you didn't write. Mock the dependency wrapper with the anticipated or hypothetical outputs.
public sealed class SomeBadDependency
{
public int CalculateSuperSecretValue(int inputX, int inputY)
{
return Math.Max(inputX, inputY);
}
}
public interface IDependencyWrapper
{
int CalculateSuperSecretValue(int inputX, int inputY);
}
public sealed class DependencyWrapper : IDependencyWrapper
{
private readonly SomeBadDependency _someBadDependency;
public DependencyWrapper(SomeBadDependency someBadDependency)
{
_someBadDependency = someBadDependency;
}
public int CalculateSuperSecretValue(int inputX, int inputY)
{
return _someBadDependency.CalculateSuperSecretValue(inputX, inputY);
}
}
public sealed class YourCode
{
private readonly IDependencyWrapper _dependencyWrapper;
public YourCode(IDependencyWrapper dependencyWrapper)
{
_dependencyWrapper = dependencyWrapper;
}
public decimal CalculateYourValue(decimal inputX, decimal inputY)
{
return _dependencyWrapper.CalculateSuperSecretValue((int) inputX, (int) inputY);
}
}
I am writing a test that depends on the results of an extension method but I don't want a future failure of that extension method to ever break this test. Mocking that result seemed the obvious choice but Moq doesn't seem to offer a way to override a static method (a requirement for an extension method). There is a similar idea with Moq.Protected and Moq.Stub, but they don't seem to offer anything for this scenario. Am I missing something or should I be going about this a different way?
Here is a trivial example that fails with the usual "Invalid expectation on a non-overridable member". This is a bad example of needing to mock an extension method, but it should do.
public class SomeType {
int Id { get; set; }
}
var ListMock = new Mock<List<SomeType>>();
ListMock.Expect(l => l.FirstOrDefault(st => st.Id == 5))
.Returns(new SomeType { Id = 5 });
As for any TypeMock junkies that might suggest I use Isolator instead: I appreciate the effort since it looks like TypeMock could do the job blindfolded and inebriated, but our budget isn't increasing any time soon.
Extension methods are just static methods in disguise. Mocking frameworks like Moq or Rhinomocks can only create mock instances of objects, this means mocking static methods is not possible.
If you can change the extension methods code then you can code it like this to be able to test:
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
public static class MyExtensions
{
public static IMyImplementation Implementation = new MyImplementation();
public static string MyMethod(this object obj)
{
return Implementation.MyMethod(obj);
}
}
public interface IMyImplementation
{
string MyMethod(object obj);
}
public class MyImplementation : IMyImplementation
{
public string MyMethod(object obj)
{
return "Hello World!";
}
}
So the extention methods are only a wrapper around the implementation interface.
(You could use just the implementation class without extension methods which are sort of syntactic sugar.)
And you can mock the implementation interface and set it as implementation for the extensions class.
public class MyClassUsingExtensions
{
public string ReturnStringForObject(object obj)
{
return obj.MyMethod();
}
}
[TestClass]
public class MyTests
{
[TestMethod]
public void MyTest()
{
// Given:
//-------
var mockMyImplementation = new Mock<IMyImplementation>();
MyExtensions.Implementation = mockMyImplementation.Object;
var myClassUsingExtensions = new MyClassUsingExtensions();
// When:
//-------
var myObject = new Object();
myClassUsingExtensions.ReturnStringForObject(myObject);
//Then:
//-------
// This would fail because you cannot test for the extension method
//mockMyImplementation.Verify(m => m.MyMethod());
// This is success because you test for the mocked implementation interface
mockMyImplementation.Verify(m => m.MyMethod(myObject));
}
}
I know this question hasn't been active for about a year but Microsoft released a framework to handle exactly this called Moles.
Here are a few tutorials as well:
DimeCasts.net
Nikolai Tillman's Tutorial
I created a wrapper class for the extension methods that I needed to mock.
public static class MyExtensions
{
public static string MyExtension<T>(this T obj)
{
return "Hello World!";
}
}
public interface IExtensionMethodsWrapper
{
string MyExtension<T>(T myObj);
}
public class ExtensionMethodsWrapper : IExtensionMethodsWrapper
{
public string MyExtension<T>(T myObj)
{
return myObj.MyExtension();
}
}
Then you can mock the wrapper methods in your tests and code with your IOC container.
For extension methods I normally use the following approach:
public static class MyExtensions
{
public static Func<int,int, int> _doSumm = (x, y) => x + y;
public static int Summ(this int x, int y)
{
return _doSumm(x, y);
}
}
It allows to inject _doSumm fairly easy.
Best thing you can do is to provide a custom implementation for the type that has the extension method, e.g:
[Fact]
public class Tests
{
public void ShouldRunOk()
{
var service = new MyService(new FakeWebHostEnvironment());
// Service.DoStuff() internally calls the SomeExtensionFunction() on IWebHostEnvironment
// Here it works just fine as we provide a custom implementation of that interface
service.DoStuff().Should().NotBeNull();
}
}
public class FakeWebHostEnvironment : IWebHostEnvironment
{
/* IWebHostEnvironment implementation */
public bool SomeExtensionFunction()
{
return false;
}
}
I know that it is not possible to Mock a concrete class but only interfacecs and abstract classes.
Is there any way or any pattern to skirt this?
For example I have the following classes that do not implement any interface. I don't want to create a new instance of C since it will take lot of time in my unit test, how can I mock it and do unit test on Foo()?
public class A
{
public virtual void Foo(){}
}
public class C:A
{
public C()
{
// construction takes lot of time
}
public override void Foo()
{
}
}
Thanks
Disclaimer I work at Typemock.
I know that it is not possible to Mock a concrete class but only
interfaces and abstract classes
With Typemock Isolator you can mock everything, from abstract classes and interfaces to sealed and static classes.
I changed your example a little:
public class A
{
public virtual int Foo() { return 0; }
}
public class C : A
{
public C()
{
// construction takes lot of time
}
private int Bar()
{
return 3;
}
public override int Foo()
{
return Bar() + 1;
}
}
[TestClass]
public class Collections
{
[TestMethod]
public void FakingWithIsolatorExample()
{
var fakeC = Isolate.Fake.Instance<C>();
Isolate.WhenCalled(() => fakeC.Foo()).CallOriginal();
Isolate.NonPublic.WhenCalled(fakeC, "Bar").WillReturn(10);
int result = fakeC.Foo();
Assert.AreEqual(11, result);
}
}
Comments:
The ctor of C was ignored.
The real implementation of Foo was called and tested
A return value was assigned to private method of C.
No changes in your code and additional levels of indirection were needed.
I am writing a test that depends on the results of an extension method but I don't want a future failure of that extension method to ever break this test. Mocking that result seemed the obvious choice but Moq doesn't seem to offer a way to override a static method (a requirement for an extension method). There is a similar idea with Moq.Protected and Moq.Stub, but they don't seem to offer anything for this scenario. Am I missing something or should I be going about this a different way?
Here is a trivial example that fails with the usual "Invalid expectation on a non-overridable member". This is a bad example of needing to mock an extension method, but it should do.
public class SomeType {
int Id { get; set; }
}
var ListMock = new Mock<List<SomeType>>();
ListMock.Expect(l => l.FirstOrDefault(st => st.Id == 5))
.Returns(new SomeType { Id = 5 });
As for any TypeMock junkies that might suggest I use Isolator instead: I appreciate the effort since it looks like TypeMock could do the job blindfolded and inebriated, but our budget isn't increasing any time soon.
Extension methods are just static methods in disguise. Mocking frameworks like Moq or Rhinomocks can only create mock instances of objects, this means mocking static methods is not possible.
If you can change the extension methods code then you can code it like this to be able to test:
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
public static class MyExtensions
{
public static IMyImplementation Implementation = new MyImplementation();
public static string MyMethod(this object obj)
{
return Implementation.MyMethod(obj);
}
}
public interface IMyImplementation
{
string MyMethod(object obj);
}
public class MyImplementation : IMyImplementation
{
public string MyMethod(object obj)
{
return "Hello World!";
}
}
So the extention methods are only a wrapper around the implementation interface.
(You could use just the implementation class without extension methods which are sort of syntactic sugar.)
And you can mock the implementation interface and set it as implementation for the extensions class.
public class MyClassUsingExtensions
{
public string ReturnStringForObject(object obj)
{
return obj.MyMethod();
}
}
[TestClass]
public class MyTests
{
[TestMethod]
public void MyTest()
{
// Given:
//-------
var mockMyImplementation = new Mock<IMyImplementation>();
MyExtensions.Implementation = mockMyImplementation.Object;
var myClassUsingExtensions = new MyClassUsingExtensions();
// When:
//-------
var myObject = new Object();
myClassUsingExtensions.ReturnStringForObject(myObject);
//Then:
//-------
// This would fail because you cannot test for the extension method
//mockMyImplementation.Verify(m => m.MyMethod());
// This is success because you test for the mocked implementation interface
mockMyImplementation.Verify(m => m.MyMethod(myObject));
}
}
I know this question hasn't been active for about a year but Microsoft released a framework to handle exactly this called Moles.
Here are a few tutorials as well:
DimeCasts.net
Nikolai Tillman's Tutorial
I created a wrapper class for the extension methods that I needed to mock.
public static class MyExtensions
{
public static string MyExtension<T>(this T obj)
{
return "Hello World!";
}
}
public interface IExtensionMethodsWrapper
{
string MyExtension<T>(T myObj);
}
public class ExtensionMethodsWrapper : IExtensionMethodsWrapper
{
public string MyExtension<T>(T myObj)
{
return myObj.MyExtension();
}
}
Then you can mock the wrapper methods in your tests and code with your IOC container.
For extension methods I normally use the following approach:
public static class MyExtensions
{
public static Func<int,int, int> _doSumm = (x, y) => x + y;
public static int Summ(this int x, int y)
{
return _doSumm(x, y);
}
}
It allows to inject _doSumm fairly easy.
Best thing you can do is to provide a custom implementation for the type that has the extension method, e.g:
[Fact]
public class Tests
{
public void ShouldRunOk()
{
var service = new MyService(new FakeWebHostEnvironment());
// Service.DoStuff() internally calls the SomeExtensionFunction() on IWebHostEnvironment
// Here it works just fine as we provide a custom implementation of that interface
service.DoStuff().Should().NotBeNull();
}
}
public class FakeWebHostEnvironment : IWebHostEnvironment
{
/* IWebHostEnvironment implementation */
public bool SomeExtensionFunction()
{
return false;
}
}