How to mock a call to a base method? - c#

tldr; How do I mock a call to a base method (using moq)?
I need to find a way to either workaround a problem regarding mocking a method that belongs to the class I inherit from, or to actually be able to just mock it.
I will start by posting some code:
The code to test:
public class CustomProductListingService : ProductListingService
{
public override IEnumerable<Product> ListAllProducts(ICategory category)
{
//does some internal filtering and to the developer unkown magic..
//would like to mock the result of this call..
var baseResult = base.ListAllProducts(category);
if(category.Name.StartsWith("A"))
return baseResult.Where(p => p.Name.StartsWith("A"));
else if(category.Name.StartsWith("B"))
return baseResult.Where(p => p.Name.StartsWith("B"));
else
return baseResult;
}
}
The test:
[TestMethod]
public void CustomProductListingService_ShouldOnlyReturnProductsWithNameStartingWithA()
{
//arrange
var customProductListingService = new CustomProductListingService();
ICategory category = new category
{
Name = "Abcd"
};
//act
var result = customProductListingService.ListAllProducts(category);
//assert
foreach(var product in result)
{
Assert.IsTrue(product.StartsWith("A"));
}
}
as you can see I call base.ListAllProducts from within my own implementation of ListAllProducts, now what I would like to be able to do is to mock base.ListAllProducts since I really dont care about what that method does internally and want to be able to control the outcome(return) so I can test my own implementation.
However, there is also another issue, this code is all a part of an implementation for an existing system, where the system normally would just inject the ProductListingService using a DI, but in my case I needed some custom behaviour and thats why the CustomProductListingService exists. What I have basically done then is to override the default registration of the system for ProductListingService and instead told it to inject my custom class CustomProductListingService.
In this case the DI-framework used is StructureMap, so basically the resultning container registration would end up looking something like:
var container = new Container(c =>
{
//use system implementation
c.For<ProductListingService>().Use<ProductListingService>();
//override system with my implementation
c.For<ProductListingService>().Use<CustomProductListingService>();
});
This then causes a problem where I cant simply do this:
public class CustomProductListingService : ProductListingService
{
private readonly ProductListingService _productListingService;
public CustomProductListingService(ProductListingService productListingService)
{
this._productListingService = productListingService;
}
public override IEnumerable<Product> ListAllProducts(ICategory category)
{
//does some internal filtering and to the developer unkown magic..
//would like to mock the result of this call..
var baseResult = this._productListingService.ListAllProducts(category);
if(category.Name.StartWith("A"))
return baseResult.Where(p => p.Name.StartWith("A"));
else if(category.Name.StartWith("B"))
return baseResult.Where(p => p.Name.StartWith("B"));
else
return baseResult;
}
}
Since that would cause a circular dependency and would be sort of strange to inject an instance thats the same type as the class I inherit from. (If this was possible I could simply mock the instance thats passed as a parameter to the constructor).
Any ideas of how to get around this?
Should probably add that the mocking-framework Im using is Moq, if that somehow makes this easier to solve.

Related

Creating a Moq of a static extension method from LLBLGen

i'm trying to use Moq to mock an extension method from the IDataAccessAdapter interface from LLBLGen. Here is FetchQueryAsync the extension method.
Doing so gave me the error that i can't Mock static extension methods. However there is no way i can change the code. So i tried creating a wrapper class, yet i had no success doing that either because i do not know how to apply it.
In the method Fetch, i want FetchQueryAsync to return an object i specified during the test and not actually execute the query.
public class QueryHandler
{
private IDataAccessAdapterProvider dataAccessAdapterProvider;
public QueryHandler(IDataAccessAdapterProvider provider)
{
this.dataAccessAdapterProvider = provider;
}
private async Task<T> Fetch(DynamicQuery<T> query)
{
using (IDataAccessAdapter adapter = dataAccessAdapterProvider.Provide()
{
result = await adapter.FetchQueryAsync(query)
}
}
}
public class DataAccessAdapterProvider : IDataAccessAdapterProvider
{
public IDataAccessAdapter Provide()
{
var adapter = new DataAccessAdapter();
return adapter;
}
}
So in my Unit Test i have this:
List<int> il = new List<int>();
Mock<IDataAccessAdapterProvider> mock = new Mock<IDataAccessAdapterProvider>();
mock.Setup(m => m.Provide()
.FetchQueryAsync<int>(It.IsAny<DynamicQuery<int>>()))
.ReturnsAsync(il);
This won't work however because it's not supported.
So i tried wrapping the method as such.
interface IWrap
{
Task<List<TElement>> FetchQueryAsync<TElement>(IDataAccessAdapter adapter, DynamicQuery<TElement> query);
}
public class Wrap : IWrap
{
public async Task<List<TElement>> FetchQueryAsync<TElement>(IDataAccessAdapter adapter, DynamicQuery<TElement> query)
{
return await adapter.FetchQueryAsync(query);
}
}
How do i apply this wrapper with Moq to mock the interface?
You started with an extension method and then you created your IWrap interface along with an implementation that uses the extension method. That's perfect.
Now all you need is to inject it into your class, just like IDataAccessAdapterProvider is already injected:
public class QueryHandler
{
private readonly IDataAccessAdapterProvider _dataAccessAdapterProvider;
private readonly IWrap _wrap; //I'm assuming you'll want a different name.
public QueryHandler(IDataAccessAdapterProvider provider, IWrap wrap)
{
_dataAccessAdapterProvider = provider;
_wrap = wrap;
}
(I applied a common convention there. Prefixing the field names with an underscore - _wrap - means that the field and constructor arguments have different names, so you don't need to specify this.wrap. Plus when people see that underscore elsewhere they'll know it's a field.)
Now you can mock the interface:
var mock = new Mock<IWrap>();
var returnedFromMock = new List<int> { 1, 2, 3 };
mock.Setup(x => x.FetchQueryAsync<int>(It.IsAny<IDataAccessAdapter>(), It.IsAny<DynamicQuery<int>>()))
.ReturnsAsync(returnedFromMock);
You mentioned that there is no way you can change the code. I'm not sure which part you can't change, but if you can't change QueryHandler to replace its concrete dependencies then this may just be a cautionary tale about static dependencies.
You have the source code, though. If you can't change the existing class, perhaps you can just create a new one from the existing source code. If someone asks why you duplicated an existing class, just say (tactfully) that you don't want to duplicate code - you'd rather fix the existing one so that it's testable.

How to Mock Base Class Property or Method in C#

i surf over internet for mock base class member in Nunit test case with no luck and finally decide to ask this scrap to stack overflow community.
Below code snippet has scenario in my application. i am going to write unit test for BankIntegrationController class and i want to make stub data or make mock for IsValid property and Print method.
Fremwork : Moq,Nunit
public class CController : IController
{
public bool IsValid {get;set;}
public string Print()
{
return // some stuff here;
}
}
public class BankIntegrationController : CController, IBankIntegration
{
public object Show()
{
if(this.IsValid)
{
var somevar = this.Print();
}
return; //some object
}
}
You don't need to mock anything. Just set the property before calling Show:
[Fact]
public void Show_Valid()
{
var controller = new BankIntegrationController { Valid = true };
// Any other set up here...
var result = controller.Show();
// Assertions about the result
}
[Fact]
public void Show_Invalid()
{
var controller = new BankIntegrationController { Valid = false };
// Any other set up here...
var result = controller.Show();
// Assertions about the result
}
Mocking is a really valuable technique when you want to specify how a dependency would behave in a particular scenario (and particularly when you want to validate how your code interacts with it), but in this situation you don't have any dependencies (that you've shown us). I've observed a lot of developers reaching for mocks unnecessarily, in three situations:
When there's no dependency (or other abstract behaviour) involved, like this case
When a hand-written fake implementation would lead to simpler tests
When an existing concrete implementation would be easier to use. (For example, you'd rarely need to mock IList<T> - just pass in a List<T> in your tests.)

Unit testing extension methods, had a go, is this right, or gone around the houses?

I have my POCO library and i have entities that implement an interface called IEntityDelete.
Interface is very simple, looks something like this
public interface IEntityDelete
{
bool IsDeleted { get; set; }
}
So i have an entity that implements this interface, again very simple, looks something like this
public class MyEntity() : IEntityDelete
{
public bool IsDeleted { get; set; }
}
I have an extension method, which i created this like
public static void MarkAsDeleted(this IEntityDelete entity)
{
entity.IsDeleted = true;
}
Then i needed to check if this method was being called within one of my service methods in my unit tests. Service method is very basic, looks something like this.
public Task<int> DeleteByFlagAsync(MyEntity entity)
{
entity.MarkAsDeleted();
return _context.SaveChangesAsync();
}
Apparently you cannot test extension methods easily, without using Microsofts Moles framework, but i do not want another dependency.
I did some googl'ing and found 2 articles on this, and how to do about it, and would like to know if this is correct, or whether i have done something stupid.
Two articles i found where
http://adventuresdotnet.blogspot.co.uk/2011/03/mocking-static-methods-for-unit-testing.html
http://blogs.clariusconsulting.net/kzu/how-to-mock-extension-methods/
They recommend using a wrapper class which aint static, so i ended up with this.
First created my wrapper interface
public interface IEntityDeleteWrapper
{
void MarkAsDeleted(IEntityDelete entity);
}
Create a class that implements this interface
public class EntityDeleteWrapper : IEntityDeleteWrapper
{
public void MarkAsDeleted(IEntityDelete entity)
{
entity.IsDeleted = true;
entity.DeletedDate = DateTime.Now;
entity.DeletedByUserId = 546372819;
}
}
Inject this interface into my service constructor
public MyService(IEntityDeleteWrapper deleteWrapper)
{
_deleteWrapper = deleteWrapper;
}
Change my service method call to use the wrapper like so
public Task<int> DeleteByFlagAsync(MyEntity entity)
{
_deleteWrapper.MarkAsDeleted(entity);
return _context.SaveChangesAsync();
}
SOLVED
As i was told, this was way too far to go, i can just check if a property has changed. In light of this, i am using my extension method still and updated my unit test to this.
[TestMethod]
public void should_mark_entity_as_deleted()
{
// arrange
var entity = new Attachment
{
IsDeleted = false
};
// act
var result = _service.DeleteByFlagAsync(entity).Result;
// assert
Assert.AreEqual(true, entity.IsDeleted);
_context.Verify(e => e.SaveChangesAsync(), Times.Once);
}
You went too far. Your test should verify observable change to state, not how that change was made. Otherwise you make your tests very brittle, not to mention you add rather unnecessary extra layer. It would be enough to check whether entity properties changed after DeleteByFlagAsync call.
Of course, when deleting gets more complex introducing dependency to delegate this task to makes sense. But then, few questions arise:
What would be the scope of DeleteByFlagAsync? Call two dependencies?
Would it be practical to test it?
...or perhaps tests for said dependency would suffice (as this is where the actual mark-for-deletion will take place)?

Moq - mock.Object.MyMethod mocking does not work

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.

Moq and constructors - testing initialisation behaviour

I'd like to be able to test a class initialises correctly using Moq:
class ClassToTest
{
public ClassToTest()
{
Method1(#"C:\myfile.dat")
}
public virtual void Method1(string filename)
{
// mock this method
File.Create(filename);
}
}
I thought I'd be able to use the CallBase property to create a testable version of the class, then use .Setup() to ensure Method1() does not execute any code.
However, creating the Mock<ClassToTest>() doesn't call the constructor, and if it did it'd be too late to do the Setup()!
If this is impossible, what is the best way round the problem whilst ensuring that the constructor behaves correctly?
EDIT: To make it clearer, I've added a parameter to Method1() to take a filename and added some behaviour. The test I'd like to write would be a working version of the following:
[Test]
public void ClassToTest_ShouldCreateFileOnInitialisation()
{
var mockClass = new Mock<ClassToTest>() { CallBase = true };
mockClass.Setup(x => x.Method1(It.IsAny<string>());
mockClass.Verify(x => x.Method1(#"C:\myfile.dat"));
}
Way down inside of Moq.Mock (actually inside the CastleProxyFactory that Moq uses)
mockClass.Object
will call the constructor by way of Activator.CreateInstance()
So your test would look something like
[Test]
public void ClassToTest_ShouldCreateFileOnInitialisation()
{
Mock<ClassToTest> mockClass = new Mock<ClassToTest>();
mockClass.Setup(x => x.Method1(It.IsAny<string>());
var o = mockClass.Object;
mockClass.Verify(x => x.Method1(#"C:\myfile.dat"));
}

Categories