public class Controller
{
public GetSomeData()
{
retun someData;
}
public dosomthing(Some someObj)
{
var getData = GetSomeData();
return service.DosomethingElse(getData);
}
}
I have mocked service.DosomethingElse(getData);.
I've also mocked GetSomeData(); but it returns "" (blank value) I want to return with "myData".
I've written a TestMethod like this:
string someData ="myData";
var mockData = new Mock<Controller>();
mockData.Setup(x => x.GetSomeData()).Returns(someData);
var mockDa = new Mock<Service>();
mockDa.Setup(x => x.DosomethingElse(getData)).Returns(response);
Controller cObj= new Controller(mockDa.Object);
var actual = cObj.dosomthing(Some someObj);
Assert.AreEqual("expected",actual);
Please suggest how to mock GetSomeData() method of the same class.
You can't do that. You can't mock the GetSomeData for the controller you are testing. You can only mock the dependencies you inject to the class.
Think about it this way:
A mock is an object with specific behavior, mocking a real class object
A class object has the proper behavior
You can't have a hybrid object, a little bit of mock and a little bit of class.
By the way, even if you could, you shouldn't. When you are testing a method, you also test the other methods of the same class that are used within. This is also the way you are testing the private functions of a class.
Related
I have a preexisting Interface...
public interface ISomeInterface
{
void SomeMethod();
}
and I've extended this intreface using a mixin...
public static class SomeInterfaceExtensions
{
public static void AnotherMethod(this ISomeInterface someInterface)
{
// Implementation here
}
}
I have a class thats calling this which I want to test...
public class Caller
{
private readonly ISomeInterface someInterface;
public Caller(ISomeInterface someInterface)
{
this.someInterface = someInterface;
}
public void Main()
{
someInterface.AnotherMethod();
}
}
and a test where I'd like to mock the interface and verify the call to the extension method...
[Test]
public void Main_BasicCall_CallsAnotherMethod()
{
// Arrange
var someInterfaceMock = new Mock<ISomeInterface>();
someInterfaceMock.Setup(x => x.AnotherMethod()).Verifiable();
var caller = new Caller(someInterfaceMock.Object);
// Act
caller.Main();
// Assert
someInterfaceMock.Verify();
}
Running this test however generates an exception...
System.ArgumentException: Invalid setup on a non-member method:
x => x.AnotherMethod()
My question is, is there a nice way to mock out the mixin call?
I have used a Wrapper to get around this problem. Create a wrapper object and pass your mocked method.
See Mocking Static Methods for Unit Testing by Paul Irwin, it has nice examples.
You can't "directly" mock static method (hence extension method) with mocking framework. You can try Moles (http://research.microsoft.com/en-us/projects/pex/downloads.aspx), a free tool from Microsoft that implements a different approach.
Here is the description of the tool:
Moles is a lightweight framework for test stubs and detours in .NET that is based on delegates.
Moles may be used to detour any .NET method, including non-virtual/static methods in sealed types.
You can use Moles with any testing framework (it's independent about that).
I found that I had to discover the inside of the extension method I was trying to mock the input for, and mock what was going on inside the extension.
I viewed using an extension as adding code directly to your method. This meant I needed to mock what happens inside the extension rather than the extension itself.
I like to use the wrapper (adapter pattern) when I am wrapping the object itself. I'm not sure I'd use that for wrapping an extension method, which is not part of the object.
I use an internal Lazy Injectable Property of either type Action, Func, Predicate, or delegate and allow for injecting (swapping out) the method during a unit test.
internal Func<IMyObject, string, object> DoWorkMethod
{
[ExcludeFromCodeCoverage]
get { return _DoWorkMethod ?? (_DoWorkMethod = (obj, val) => { return obj.DoWork(val); }); }
set { _DoWorkMethod = value; }
} private Func<IMyObject, string, object> _DoWorkMethod;
Then you call the Func instead of the actual method.
public object SomeFunction()
{
var val = "doesn't matter for this example";
return DoWorkMethod.Invoke(MyObjectProperty, val);
}
For a more complete example, check out http://www.rhyous.com/2016/08/11/unit-testing-calls-to-complex-extension-methods/
If you just want to make sure that the extension method was invoked, and you aren't trying to setup a return value, then you can check the Invocations property on the mocked object.
Like this:
var invocationsCount = mockedObject.Invocations.Count;
invocationsCount.Should().BeGreaterThan(0);
Reason why it is not possible to mock an extension method is already given in good answers. I am just trying to give another possible solution with this answer: Extract a protected, virtual method with the call to the extension method and create a setup for this method in the test class/method by using a proxy.
public class Foo
{
public void Method()
=> CallToStaticMethod();
protected virtual void CallToStaticMethod()
=> StaticClass.StaticMethod();
}
and test
[TestMethod]
public void MyTestMethod()
{
var expected = new Exception("container exception");
var proxy = new Mock<Foo>();
proxy.Protected().Setup("CallToStaticMethod").Throws(expected);
var actual = Assert.ThrowsException<Exception>(() => proxy.Object.Foo());
Assert.AreEqual(expected, actual);
}
In my case extension method is a method around some public method of my class. So I checked call of that internal method. That approach is similar to Alvis answer (above).
So if you are using Moq, and want to mock the result of an Extension method, then you can use SetupReturnsDefault<ReturnTypeOfExtensionMethod>(new ConcreteInstanceToReturn()) on the instance of the mock class that has the extension method you are trying to mock.
It is not perfect, but for unit testing purposes it works well.
I have an instantiation in constructor in test:
public class Car{
public string Method()
{
return "test";
}
}
private readonly ICar _classUnderTest;
public CarTests()
{
var collaboratingClass = new CollaboratingClass();
_classUnderTest = new Car(collaboratingClass );
}
If I use moq and pass mock instance like this:
var collaboratingClass = new Mock<ICollaboratingClass>();
_classUnderTest = new Car(collaboratingClass .Object);
...then I can't call method. The method from this mocked instance is not being called, so I can't use it for calculation. How can I make my mock object to be able to access method and do operation with mock object?
As you can see I don't want to have concrete dependencies here.
You can fake a return to your mocked class method. If you need the behavior from your dependency, it's no longer a unit test
I have the following code:
public interface IProductDataAccess
{
bool CreateProduct(Product newProduct);
}
Class ProductDataAccess implements that interface.
public class ProductBusiness
{
public bool CreateProduct(Product newProduct)
{
IProductDataAccess pda = new ProductDataAccess();
bool result = pda.CreateProduct(newProduct);
return result;
}
}
In this case, how to create unit test for CreateProduct method by mocking the IProductDataAccess interface? I thought of having an public instance of IProductDataAccess within ProductBusiness and initialize it using Mock<IProductDataAccess> object but it is not a good practice to expose the data access to the UI layer. Can any one help me?
Classic example which demonstrates that if you cannot unit test a particular component, REFACTOR it!
This is why I love what any mocking framework enforces you to do - write decoupled code.
In your example, the ProductBusiness class is tightly coupled with the ProductDataAccess class. You could decouple it using (like most of the answers suggest) dependency injection. By doing so, you would end up depending on the IProductDataAccess abstraction and not on any concrete implementation of it.
Another point to note, when you are writing tests/specifications for the business layer, you would typically want to test the "behavior" and not the "state". So, although you could have asserts that verify if "true" was returned, your tests should really test if the expected data access calls that were set using MOQ were actually executed using the .Verify API of MOQ.
Try adding behavior tests where you expect an exception to be thrown (using the ".Throws" API) by the data access layer and check if you need any special handling at the business layer.
Like Kevin suggests, the following implementation of ProductBusiness will work:
public class ProductBusiness
{
private readonly IProductDataAccess _productDataAccess;
public ProductBusiness(IProductDataAccess productDataAccess)
{
_productDataAccess = productDataAccess;
}
public bool CreateProduct(Product newProduct)
{
bool result=_productDataAccess.CreateProduct(newProduct);
return result;
}
}
and use any xunit testing framework to write the test as:
var mockDataAccess = new Mock<IProductDataAccess>();
mockDataAccess.Setup(m => m.CreateProduct(It.IsAny<Product>())).Returns(true);
var productBusiness = new ProductBusiness(mockDataAccess.Object);
//behavior to be tested
You should inject IProductDataAccess interface as a dependency:
public class ProductBusiness
{
private IProductDataAccess _productDataAccess;
public ProductBusiness(IProductDataAccess productDataAccess)
{
_productDataAccess = productDataAccess;
}
public bool CreateProduct(Product newProduct)
{
bool result = _productDataAccess.CreateProduct(newProduct);
return result;
}
}
Then you can replace it with a mock in your tests:
var productDataAccess = new Mock<IProductDataAccess>();
var productBusiness = new ProductBusiness(productDataAccess.Object);
With the way that you have currently designed your ProductBusiness class there is no way of changing the IProductDataAccess implementation using a mock. A recommended pattern for this is dependency-injection where you take the dependencies of a type through the constructor. So your class becomes:
public class ProductBusiness
{
private readonly IProductDataAccess _productDataAccess;
public ProductBusiness(IProductDataAccess productDataAccess)
{
_productDataAccess = productDataAccess;
}
public bool CreateProduct(Product newProduct)
{
bool result = _productDataAccess.CreateProduct(newProduct);
return result;
}
}
Now you are in a position to test your class by using a mocking framework like moq. For example:
var mockDataAccess = new Mock<IProductDataAccess>();
mockDataAccess
.Setup(m => m.CreateProduct(It.IsAny<Product>()))
.Returns(true);
var productBusiness = new ProductBusiness(mockDataAccess.Object);
// ... test behaviour here
Now you can change how the mock behaves in your setup step and make sure that your CreateProduct method is behaving correctly.
I would also look at a dependency injection framework like castle-windsor. A dependency injection framework can automatically resolve dependencies meaning creating a new type is much easier as you don't have to manually new everything up. Also it means that you can change which implementation is used in one place and it changes everywhere.
You shouldn't instantiate a concrete ProductDataAccess inside your CreateProduct method.
Instead, IProductDataAccess should be an injectable dependency. This can be done in one of two ways:
Property injection:
public class ProductBusiness
{
IProductDataAccess Pda {get; set;}
}
var productBusiness = new ProductBusiness();
productBusiness.Pda = new ProductDataAccess();
productBusiness.Pda = new MockProductDataAccess();
Or constructor injection:
public class ProductBusiness
{
private readonly IProductDataAccess _pda;
public ProductBusiness(IProductDataAccess pda)
{
_pda = pda;
}
}
var productBusiness = new ProductBusiness(new ProductDataAccess());
var productBusiness = new ProductBusiness(new MockProductDataAccess());
Constructor injection is usually the recommend approach.
Property injection is used for optional dependencies (e.g., instantiate a concrete NullLogger by default in the constructor, and use the property to optionally inject a working logger).
I have a strange trouble. I am not too familiar with Moq, being more a GUI guy. I tried to mock a factory method in my code. The factory looks like this, and returns a ISettings instance which does many IO Operations. I want it to return a memory only ISettings instance to accelerate my test.
public class SettingsFactory
{
internal ISettings mSettingsImpl;
internal virtual ISettings CreateOrGetSettings()
{
return mSettingsImpl ?? (mSettingsImpl = new XmlSettings());
}
}
and the mock is
var imocked = new Mock<SettingsFactory>() {CallBase = false};
imocked.Setup(x => x.CreateOrGetSettings()).Returns(new NonPersistingSettings());
var tryToSeeTheType = imocked.Object.CreateOrGetSettings();
the tryToSeeTheType is however XMLSettings and not NonPersistingSettings as I would expect. Stepping through results into the code shown me that it goes directly into the original factory method. Any suggestions what I do wrong here?
The "Object" property of a mocked object is not actually an instance of the class you are trying to mock.
The purpose of a mock is to be able to replace an object the method you are trying to test depends on.
Imagine that your SettingsFactory performs very expensive operations like for example accessing the network or a database or the file system. You do not want your test to access those expensive resources so you create a mock. I would be something like this:
public class ClassThatUsesSettingsFactory
{
private readonly SettingsFactory _settingsFactory;
public ClassThatUsesSettingsFactory(SettingsFactory settingsFactory)
{
_settingsFactory = settingsFactory;
}
public void MethodThatCallsSettingsFactory()
{
//... do something
var settings = _settingsFactory.CreateOrGetSettings();
//... do something
}
}
By doing this you are able to replace the SettingsFactory with a mock on your unit test like so:
[TestMethod]
public void MakeSureSettingsFactoryIsCalled()
{
var settingsFactoryMock = new Mock<SettingsFactory>();
settingsFactoryMock.Setup(f => f.CreateOrGetSettings(), Times.Once).Verifiable();
var subjectUnderTest = new ClassThatUsesSettingsFactory(settingsFactoryMock.Object);
subjectUnderTest.MethodThatCallsSettingsFactory();
settingsFactoryMock.Verify();
}
This unit test is basically only making sure that the method CreateOrGetSettings gets called once and only once when the MethodThatCallsSettingsFactory gets executed.
What Moq does is to create a different class with a different implementation of its virtual method that will, most likely, set a flag to true once it gets called and then check the value of that flag on the "Verify" method.
There is a lot to grasp here so I hope it is clear enough since you mentioned that you do not have a lot of experience with Moq.
I have a preexisting Interface...
public interface ISomeInterface
{
void SomeMethod();
}
and I've extended this intreface using a mixin...
public static class SomeInterfaceExtensions
{
public static void AnotherMethod(this ISomeInterface someInterface)
{
// Implementation here
}
}
I have a class thats calling this which I want to test...
public class Caller
{
private readonly ISomeInterface someInterface;
public Caller(ISomeInterface someInterface)
{
this.someInterface = someInterface;
}
public void Main()
{
someInterface.AnotherMethod();
}
}
and a test where I'd like to mock the interface and verify the call to the extension method...
[Test]
public void Main_BasicCall_CallsAnotherMethod()
{
// Arrange
var someInterfaceMock = new Mock<ISomeInterface>();
someInterfaceMock.Setup(x => x.AnotherMethod()).Verifiable();
var caller = new Caller(someInterfaceMock.Object);
// Act
caller.Main();
// Assert
someInterfaceMock.Verify();
}
Running this test however generates an exception...
System.ArgumentException: Invalid setup on a non-member method:
x => x.AnotherMethod()
My question is, is there a nice way to mock out the mixin call?
I have used a Wrapper to get around this problem. Create a wrapper object and pass your mocked method.
See Mocking Static Methods for Unit Testing by Paul Irwin, it has nice examples.
You can't "directly" mock static method (hence extension method) with mocking framework. You can try Moles (http://research.microsoft.com/en-us/projects/pex/downloads.aspx), a free tool from Microsoft that implements a different approach.
Here is the description of the tool:
Moles is a lightweight framework for test stubs and detours in .NET that is based on delegates.
Moles may be used to detour any .NET method, including non-virtual/static methods in sealed types.
You can use Moles with any testing framework (it's independent about that).
I found that I had to discover the inside of the extension method I was trying to mock the input for, and mock what was going on inside the extension.
I viewed using an extension as adding code directly to your method. This meant I needed to mock what happens inside the extension rather than the extension itself.
If you just want to make sure that the extension method was invoked, and you aren't trying to setup a return value, then you can check the Invocations property on the mocked object.
Like this:
var invocationsCount = mockedObject.Invocations.Count;
invocationsCount.Should().BeGreaterThan(0);
I like to use the wrapper (adapter pattern) when I am wrapping the object itself. I'm not sure I'd use that for wrapping an extension method, which is not part of the object.
I use an internal Lazy Injectable Property of either type Action, Func, Predicate, or delegate and allow for injecting (swapping out) the method during a unit test.
internal Func<IMyObject, string, object> DoWorkMethod
{
[ExcludeFromCodeCoverage]
get { return _DoWorkMethod ?? (_DoWorkMethod = (obj, val) => { return obj.DoWork(val); }); }
set { _DoWorkMethod = value; }
} private Func<IMyObject, string, object> _DoWorkMethod;
Then you call the Func instead of the actual method.
public object SomeFunction()
{
var val = "doesn't matter for this example";
return DoWorkMethod.Invoke(MyObjectProperty, val);
}
For a more complete example, check out http://www.rhyous.com/2016/08/11/unit-testing-calls-to-complex-extension-methods/
Reason why it is not possible to mock an extension method is already given in good answers. I am just trying to give another possible solution with this answer: Extract a protected, virtual method with the call to the extension method and create a setup for this method in the test class/method by using a proxy.
public class Foo
{
public void Method()
=> CallToStaticMethod();
protected virtual void CallToStaticMethod()
=> StaticClass.StaticMethod();
}
and test
[TestMethod]
public void MyTestMethod()
{
var expected = new Exception("container exception");
var proxy = new Mock<Foo>();
proxy.Protected().Setup("CallToStaticMethod").Throws(expected);
var actual = Assert.ThrowsException<Exception>(() => proxy.Object.Foo());
Assert.AreEqual(expected, actual);
}
In my case extension method is a method around some public method of my class. So I checked call of that internal method. That approach is similar to Alvis answer (above).
So if you are using Moq, and want to mock the result of an Extension method, then you can use SetupReturnsDefault<ReturnTypeOfExtensionMethod>(new ConcreteInstanceToReturn()) on the instance of the mock class that has the extension method you are trying to mock.
It is not perfect, but for unit testing purposes it works well.