Mocking Generic Method with NSubstitute - c#

I have an interface with a number of generic methods. These methods perform operations based on the type of data that is passed in. How do I mock this with NSubstitute? At the moment, I had to resort to using a concrete class instead of a mock since I cannot handle all possible types that the method will be called with.
public interface IInstanceSource
{
bool CanCreate<T>();
T Create<T>();
void Register<T>(Func<T> creator);
}
public static IInstanceSource GetInstanceSource()
{
var _data = new Dictionary<Type, Func<object>>();
var a = Substitute.For<IInstanceSource>();
//code below fails since T is not defined. How do I make the code below accept any type?
a.WhenForAnyArgs(x=>x.Register(Arg.Any<Func<T>>)).Do(x=> { /* todo */});
a.CanCreate<T>().Returns(x => _data[typeof (T)]);
return a;
}
thanks.

NSubstitute doesn't support setting up multiple instances of a generic method automatically.
The way we'd normally see IInstanceSource used in a test is to configure it for a specific bit of code under test, so T would be known. If a single fixture needed to work for a few different Ts, we could make configuration simpler by having a helper method like ConfigureInstanceSource<T>() which would do the configurations steps for a specific T.
In your case though it seems like you want a fixed behaviour for all fake instances of IInstanceSource, in which case I believe you are going the right way about it by hand-coding your own test double.

Related

Helper method for calling generic methods with reflection

Does anyone have a better way to do the following:
typeof(Service).GetMethod("UpdateData")
.MakeGenericMethod(dataType)
.Invoke(_myService, new object[]{ editData, metaData });
I'd love to do something like:
_myService.UpdateData<dataType>(editData, metaData);
But the <> accessor for generics will not take Type objects. I'm looking for a helper, utility, accessor, or something to make those generic method calls with reflection less cumbersome or at least centralized.
More Specific Example
public class UserService : IUserService
{
async Task<User> UpdateUser<T>(User user, JsonPatchDocument<T> patch){ //do code }
}
Type dtoType = MagicService.getDynamicDtoType();
Type patchType = typeof(JsonPatchDocument<>).MakeGenericType(dtoType);
dynamic patchDoc = _mapper.Map(patch, typeof(JsonPatchDocument<User>), patchType);
User updateUser = await (Task<User>)typeof(UserService).GetMethod("UpdateUser").MakeGenericMethod(dtoType).Invoke(_userService, new object[]{user, patchDoc})
This actually ends up with two issues. One, the dynamic patchDoc isn't the right type to be used in UpdateUser, which I have a separate question in Stackoverflow about (but you can use duck typing here), and the messy calling of that generic method call with reflection. I'm trying to solve both, but for this question I want to clean up the call. If you have ideas on the other piece, which is really a separate issue:
Declaring a type in C# with a Type instance
This answer does not use reflection, but may make your code easier to work with in some circumstances.
We could have a class like this:
public class MyService
{
public void UpdateData<T>(Something data, Something otherData)
{
// do stuff
}
}
Later we find that we have to call it using a Type variable instead of a generic argument, which could mean using reflection. Sometimes it's easier to add a non-generic overload to the original class, and call it from the generic method:
public class MyService
{
public void UpdateData(Type dataType, Something data, Something otherData)
{
// do stuff
}
public void UpdateData<T>(Something data, Something otherData)
{
UpdateData(typeof(T), data, otherData);
}
}
We lose the ability to easily impose constraints on the Type argument like we could with the generic method. We can add validation if we need it.
That gets you as close as possible to the code you're trying to write:
_myService.UpdateData(dataType, editData, metaData);
That's assuming that you find yourself still needing the generic methods at all. If you add non-generic overloads and discover that you're not calling the generic ones anymore, you can just delete them.
A significant benefit of this over reflection is that you can identify where your code is called. A method that's only called using reflection will appear unused.

Mocking generic repository factory method

I've made refactoring if our repository factory to make it more generic and right now the method creating repositories looks like that:
public TRepository CreateRepository<TRepository>(params object[] parameters)
where TRepository : class
{
if (_serviceProvider == null)
throw new ArgumentNullException(nameof(_serviceProvider));
return ActivatorUtilities.CreateInstance<TRepository>(_serviceProvider, parameters);
}
In my production code I am using it like so and it works like charm:
_concreteRepo = repoFactory.CreateRepository<ConcreteRepo>();
But when I am trying to refactor unit tests as well I am having difficulties setting up the factory, this is how I do it but it doesn't work.
public class Tests
{
// Since I am using Moq I can't mock anything but abstract types thus having problems with type conversion in set up.
protected readonly Mock<IConcreteRepository> _concreteRepositoryMock = new Mock<IConcreteRepository>();
protected readonly Mock<IRepositoryFactory> _factoryMock = new Mock<IRepositoryFactory>();
[SetUp]
public void SetUp()
{
// If I don't cast concreteRepositoryMock compiler complains that cannot convert from abstract to concrete repository.
// If I cast it fails and returns null.
_factoryMock.Setup(f => f.CreateRepository<ConcreteRepository>())
.Returns(_concreteRepositoryMock.Object as ConcreteRepository);
}
}
Any idea how can workaround it? Seems like my CreateRepository method is returning concrete types, but mocking I cannot mock my concrete repository.Also I couldn't pass abstract types to CreateRepository, because CreateInstance requires concrete types.
I think your issue is that you expect the Mock object:
protected readonly Mock<IConcreteRepository> _concreteRepositoryMock = new Mock<IConcreteRepository>();
To be instance of ConcreteRepository, which is wrong assumption.
_concreteRepositoryMock.Object is IConcreteRepository
This should say "TRUE" while
_concreteRepositoryMock.Object is ConcreteRepository
This should say "FALSE".
You have to either switch your PROD code to be happy with abstraction (IConcreteRepository) or mock the final class
protected readonly Mock<ConcreteRepository> _concreteRepositoryMock = new Mock<ConcreteRepository>();
in your mock (note that mocking concrete classes is usually not easy - you need all mocked methods to be virtual etc.).
Actually I found workaround to this which I am relatively happy at the moment, but if any other suggestions appear I would love to hear them.
So problem was that my CreateRepository was returning concrete implementation while it had to return abstraction because all my mocks are abstractions (because Moq mocks only abstractions). Therefore I modified my method as follows:
TInterface CreateRepository<TRepository, TInterface>(params object[] parameters)
where TRepository : class, TInterface where TInterface : class;
And this guaranteed compile-time safety for my set up method and success afterwards. I do find it somewhat cumbersome, but I can live with it for now.
NOTE: You can always do extension method within internal class in your testing assembly and copy&paste the code from production method, this way you won't pollute your production code, however, this can be problematic if someone tries to change the production method without changing the test one, this is why I choose to "pollute" my production code for the sake of safety.

Register Generic Interfaces with UnityAutoMoqContainer

We use UnityAutoMoq for mocking most of our interfaces in our unit tests, but I've recently run into a situation where we want to use a test framework to more completely simulate the actual behavior (call it an integration test if that helps you accept what I'm doing).
I expected UnityAutoMoq to let me register concrete mappings instead of allowing the UnityAutoMoqContainer to defer to mocking the interface. This holds true to everything I've tried except for generic interfaces. In case you're visual like me, here's a snippet of what I'm trying:
public static void Register(IUnityContainer container)
{
...
container.RegisterType(typeof(IService<>), typeof(TestFrameworkService<>),
new HierarchicalLifetimeManager(), new InjectionFactory(Create));
...
}
private static object Create(IUnityContainer container, Type type, string name)
{
var T = type.GetGenericArguments().Single();
return new TestFrameworkService<T>();// For simplicity, pretend this works
}
As you can see from above, I'm registering the generic interface to a generic concrete, then depending upon the injection factory to resolve it using the incoming type (the actual implementation was omitted for simplicity). This works with a normal UnityContainer, returning the expected concrete. The UnityAutoMoqContainer returns a mock instead, bypassing the injection factory completely.
Has anyone tried anything like what I'm trying to accomplish? Any ideas?
I found that the problem lies in the underlying BuilderStrategy. Here's a snippet from UnityAutoMoqBuilderStrategy.
public override void PreBuildUp(IBuilderContext context)
{
var type = context.OriginalBuildKey.Type;
if (autoMoqContainer.Registrations.Any(r => r.RegisteredType == type))
return;
if (type.IsInterface || type.IsAbstract)
{
context.Existing = GetOrCreateMock(type);
context.BuildComplete = true;
}
}
Bottom line is that the builder strategy sees that the interface isn't registered and intercepts its creation. This is because generic type definitions aren't equal to the generic types, themselves.
I looked into AutoMoq, which was far more recently updated, but it suffers from the same interception limitation that prevents the injection factory from firing.
For reference, here are the automocking libraries that I researched:
https://github.com/thedersen/UnityAutoMoq
https://github.com/rajgit31/UnityAutoMoq
https://github.com/darrencauthon/AutoMoq
If someone has a recommendation, then please let me know, otherwise I'll consider this the answer.

Expression references a method that does not belong to the mocked object

I have an api service that calls another api service. When I set up the Mock objects, it failed with an error:
NotSupportedException: expression references a method that does not belong to the mocked object.
This is the code:
private Mock<IEnumerable<ICarrierApiService<AccountSearchModel>>> _mockCarrierService;
private Mock<IApiService<AccountSearchModel>> _mockApiService;
[SetUp]
public void SetUp()
{
_mockApiService = new Mock<IApiService<AccountSearchModel>>();
_mockCarrierService = new Mock<IEnumerable<ICarrierApiService<AccountSearchModel>>>();
_mockApiService.Setup(x => x.GetFromApiWithQuery(It.IsAny<string>())).Returns(ApiValue());
// Error occurred when call _mockApiService.GetFromApiWithQuery() in .Select()
_mockCarrierService.Setup(x => x
.Select(s => s
.GetFromApiWithQuery(It.IsAny<string>())).ToList())
.Returns(new List<IQueryable<AccountSearchModel>> { ApiValue() });
}
I read Expression testing with Moq but it didn't work for my case. If I remove this _mockCarrierService.Setup(), the test case can run but fails with a NullReferenceException because it didn't have a valid List<IQueryable<AccountSearchModel>> set up.
Any idea how I can achieve this?
Footnote: Current Solution
FWIW, here's the solution that I currently use. I am all ears for a better approach to the issue (until Moq starts supporting mocking extension methods).
private List<ICarrierApiService<AccountSearchModel>> _mockCarrierService;
private AccountSearchController _mockController;
private Mock<ICarrierApiService<AccountSearchModel>> _mockApiService;
[SetUp]
public void SetUp()
{
_mockApiService = new Mock<ICarrierApiService<AccountSearchModel>>();
_carrierServiceMocks = new List<ICarrierApiService<AccountSearchModel>> { _mockApiService.Object };
_mockApiService.Setup(x => x.GetFromApiWithQuery(It.IsAny<string>())).Returns(ApiValue());
_mockController = new AccountSearchController(_carrierServiceMocks);
}
Footnote: alternative mocking framework
I've also found a commercial mocking framework that supports mocking extension method and link to the how-to docs: Telerik JustMock.
This problem occurs because you are trying to mock Select method, which is an extension method, not an instance method of IEnumerable<T>.
Basically, there is no way to mock an extension method. Have a look at this question for some ideas that you may find useful.
UPD (12/11/2014):
To gain more understanding on mocking extension methods, think about the following:
Although extension methods are called as if they were instance methods on the extended type, they are actually just a static methods with a bit of syntactic sugar.
Extension methods from System.Linq namespace are implemented as pure functions — they are deterministic and they don't have any observable side effects. I agree that static methods are evil, except those that are pure functions — hope you would agree with this statement too :)
So, given an object of type T, how would you implement static pure function f(T obj)? It is only possible by combining other pure functions that are defined for object T (or any other pure functions, actually), or by reading immutable and deterministic global state (to keep function f deterministic and side-effect-free). Actually, "immutable and deterministic global state" has more convenient name — a constant.
So, it turns out that if you follow the rule that static methods should be pure functions (and it looks like Microsoft follows this rule, at least for the LINQ methods), mocking an extension method f(this T obj) should be reducible to mocking non-static methods or state used by that extension method — simply because that extension method relies on the obj instance methods and state in its implementation (and possibly on the other pure functions and/or constant values).
In case of IEnumerable<T>, Select() extension method is implemented in terms of foreach statement which, in turn, uses GetEnumerator() method. So you can mock GetEnumerator() and achieve required behavior for extension methods that rely on it.
You have:
_mockCarrierService = new Mock<IEnumerable<ICarrierApiService<AccountSearchModel>>>();
So you mock IEnumerable<>. The only member IEnumerable<> has is a method GetEnumerator() (plus another method with the same signature GetEnumerator() inherited from the base interface). The Select method is really an extension method (as was pointed out in the first answer) which is a static method that works by calling GetEnumerator() (possibly through C# foreach statement).
It is possible to make things work by doing Setup of GetEnumerator on your mock.
However, it is much simpler to simply use a concrete, non-mock type which "is" IEnumerable<>, such as List<>. So try:
_mockCarrierService = new List<ICarrierApiService<AccountSearchModel>>();
Then add an entry to the List<>. What you should add, is a Mock<ICarrierApiService<AccountSearchModel>> on which GetFromApiWithQuery Method is setup.
also if u need to Mock IConfiguration u can use this code below:
var builder = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string>
{
{ "your-key", "your value" }
});
var config = builder.Build();
Since the question about mocking IConfiguration is referring this answer as duplicate, I will contribute my dime here.
This is how I "Mock" IConfiguration, which is, in my opinion, a bit cleaner:
private static IConfiguration GetConfigurationMock(string jsonConfiguration)
{
var byteArray = Encoding.UTF8.GetBytes(jsonConfiguration);
var stream = new MemoryStream(byteArray);
var conf = new ConfigurationBuilder();
conf.AddJsonStream(stream);
var confRoor = conf.Build();
return confRoor;
}
Original question: How to setup Mock of IConfigurationRoot to return value

Is there any benefit (semantic or other) to using a static method that calls a constructor?

I just updated Visual Studio 2013 and I noticed that in the project template for an MVC application the ApplicationDbContext class now has a static method that just calls the constructor:
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
This seems like clutter to me but I imagine that there is some semantic reason that I should now start using ApplicationDbContext.Create() instead of new ApplicationDbContext(). Are there any benefits to doing so?
Actually. yes.
In your specific case, wrapping it thusly allows you to quickly start bolting on logic, such as making the ApplicationDbContext and singleton or handling an exception in a common way for the whole application. Since a constructor cannot return null, this can be very important to be able to catch an exception and return null.
Tuple.Create is the prime example of generic inference, which does not work with Constructors. This allows you say
Tuple.Create(Item1, Item2.. ItemN);
And the let the compiler infer types, rather than
new Tuple<T1, T2...Tn>(Item1, Item2...ItemN);
Which is more verbose, and takes a bit more work if you want to switch out one of those types.
There is also the case of Anonymous types, which cannot be specified explicitly and thus cannot be used in new statements. I have specifically had occasion where, while searching assemblies for a specific Attribute to link a command structure for, I wanted to make an enumerable (a Queue, in this case) out of an anonymous type during the search to pair class references with their constructor and string arguments, rather than looking these up every time they're needed. Since I can again use Generic inference in a method, I was able to wrap the constructor in an extension method and get the job done.
There are also cases for singleton patterns, wherein you want the "GetInstance" method to usually create a value, or get one if it exists. May not qualify since it does slightly more than wrap a constructor.
In addition, there are plenty of cases where you may want to control implementation procedures, such as forcing them onto other threads, logging them in a database to be undone later, or bolting on a permissions system, all of which can be done by making a constructor wrapper and adding a few more lines of logic, and then privatizing the constructor to avoid it being called directly.
There are also cases where I've created a factory method which delegates to known children in order to provide a different implementation of a returned interface or abstract based on provided parameters. This has the added benefit of being able to hide the implementing classes - the Type class and IEnumerable interface make use of this pattern.
This pattern can be very useful, especially if you use a private constructor, and return an interface type from the Create, rather than the concrete type.
private ApplicationDbContext()
{
}
public static IApplicationDbContext Create()
{
return new ApplicationDbContext();
}
Now consumers of your class are prevented from depending on the concrete implementation - they can only rely on the abstraction.
Wrapping the constructor with static methods (creation methods) allows you to chose a specific name that conveys information. You can also create several methods with the same parameter signature such as CreateX(float f) and CreateY(float f), which you cannot do with constructors.
A situation where this is really useful is e.g. for creating structs that represent physical quantities that may have several units, such as time, length or weight. Here, you could use creation methods to force the programmer to always explicitly specify the unit instead of just passing a unit-less number to a single constructor (which assumes a certain unit, and getting it wrong might have huge consequences).
Example:
public struct Length
{
private const double MetersPerYard = 0.9144;
private double _meters;
private Length(double meters)
{
_meters = meters;
}
public static Length FromMeters(double meters)
{
return new Length(meters);
}
public static Length FromYards(double yards)
{
return new Length(yards*MetersPerYard);
}
public double Meters
{
get { return _meters; }
}
public double Yards
{
get { return _meters / MetersPerYard; }
}
}
Or take a look at TimeSpan and methods like FromMinutes, FromSeconds etc.

Categories