Using Ninject, I have a factory registered like this:
kernel.Bind<IMyFactory>().ToFactory();
Where IMyFactory looks something like this:
public interface IMyFactory
{
T CreateInstance<T> where T : MyBaseClass;
}
The reason for this is that classes derived from MyBaseClass have their own dependencies and I needed to be able to create instances of those classes from their types which I do like this:
MethodInfo mi = factory.GetType().GetMethod("CreateFoo");
MethodInfo generic = mi.MakeGenericMethod(type);
var param = (MyBaseClass)generic.Invoke(factory, null);
Where factory is the instance of IMyFactory created by Ninject and type is the type of MyBaseClass derived class I want to create. This all works really well.
The problem is that I'd like to be able to unit test this using the testing framework in Visual Studio and Moq, but I can't figure out a good way to mock IMyFactory.
Currently I have this:
myFactory = new Mock<IMyFactory>();
myFactory.Setup(d => d.CreateFoo<MyFirstClass>()).Returns(new MyFirstClass(userService.Object));
myFactory.Setup(d => d.CreateFoo<MySecondClass>()).Returns(new MySecondClass(userService.Object, someOtherServiceMock.Object));
// repeat for as many classes as would usually be handled by IMyFactory
Obviously this is really tedious (I have a few dozen classes to do). Is there a better way to do it?
This is kind of fiddly, and I'm not sure that it's the right strategy for testing anyway, but here's one approach that seems to work. I created a function in my test class like this:
private Dictionary<Type, Mock> mocks;
private void SetupCreateFoo<T>(Mock<IMyFactory> myFactory) where T: MyBaseClass
{
var t = typeof(T);
var constructors = from constructor in t.GetConstructors()
let parameters = constructor.GetParameters()
where parameters.Length > 0
select new { constructor, parameters };
// Note: there should only be one constructor anyway
foreach (var c in constructors)
{
List<object> parameters = new List<object>();
foreach (var p in c.parameters)
{
parameters.Add(mocks[p.ParameterType].Object);
}
myFactory.Setup(d => d.CreateAnalytic<T>()).Returns((T)c.constructor.Invoke(parameters.ToArray()));
}
}
Where the dictionary mocks is a collection of mocked services that might be needed by classes derived from MyBaseClass.
Now where I setup my test class, I can do this:
[TestInitialize]
public void Setup()
{
userService = new Mock<IUserService>();
//... setup userService
someOtherServiceMock = new Mock<ISomeOtherService>();
//... setup someOtherService
mocks = new Dictionary<Type, Mock>()
{
{ typeof(IUserService), userService },
{ typeof(ISomeOtherService), someOtherServiceMock}
};
myFactory= new Mock<IMyFactory>();
SetupCreateFoo<MyFirstClass>(myFactory);
SetupCreateFoo<MySecondClass>(myFactory);
// ... etc
finderService = new FinderService(userService.Object, myFactory.Object);
}
And I think I could potentially set up a List<Type> and call SetupCreateFoo<T> in a loop to further reduce the repetition, but it would require some reflection again to call a generic method with the Type.
It's still unclear to me why you need to mock IMyFactory, but to answer your core question: no, Moq offers now way to setup a generic method for any generic type parameter. I contribute to an open source project which integrates with Moq and I've faced this limitation before.
But you should only be setting up the method for the generic type parameters that are relevant to the test. If your test needs the factory to be setup with a hand full of type parameters, then that sounds like either a code smell or an exotic edge case.
Related
Due to the way that I'm trying to integrate AutoFixture with BUnit to run some Blazor tests, I need to create an IServiceProvider that will have an internal Fixture, and I can inject objects into that fixture to have those same objects returned when AutoFixture is request to create an object of that type.
My IServiceProvider looks like this
public class MockServiceProvider : IServiceProvider
{
private readonly Fixture fixture;
public MockServiceProvider()
{
this.fixture = new Fixture();
this.fixture.Customize(new AutoMoqCustomization { ConfigureMembers = true });
}
public void RegisterServices(params object[] serviceInstances)
{
foreach (object serviceInstance in serviceInstances)
{
this.fixture.Inject(serviceInstance);
}
}
public object GetService(Type serviceType)
{
return this.fixture.Create(serviceType, new SpecimenContext(this.fixture));
}
}
Then I register my service instances like this:
[Theory, AutoDomainData]
public void TestSomething(
IMyFirstService firstService,
IMySecondService secondService,
MockServiceProvider serviceProvider)
{
serviceProvider.RegisterServices(firstService, secondService);
// test stuff
}
The problem is that any time GetService is called, the fixture returns a new service instance instead of the one I injected.
I think that the problem is that since I'm passing my service instances to RegisterServices as objects, AutoFixture doesn't register them as the type that they actually are.
I can fix the problem by registering each service instance one at a time like this...
public void RegisterService<T>(T serviceInstance)
{
this.fixture.Inject(serviceInstance);
}
... but I'm curious as to why the first method doesn't work. Even though the parameters are an object array, shouldn't AutoFixture still know their actual type? I've tried this using RegisterServices(params dynamic[] serviceInstances) as well, but that doesn't work either.
The reason why Inject<T> doesn't infer the type of the instance but rather relies on the generic parameter is because it needs to enable scenarios where it is necessary to register values for base types or interfaces fixture.Inject<AbstractBaseType>(instance).
The way Inject works behind the scenes is that it delegates the registration to Register<T>(Func<T> creator) which then delegates it to a fixture.Customize<T>(c => c.FromFactory(creator).OmitAutoProperties()). So you can see how it wouldn't work when you need type inference.
You could as you said, make registrations one by one, or you could implement your own injection. Note the implementation below is a lighter implementation of the builder that would be normally generated by AutoFixture, and should cover most scenarios. If you find that some features are not working, like seeded requests, you might need a more complete implementation of the injection.
public static void InjectAsReflectedType(this IFixture fixture, object instance)
{
var builder = new FilteringSpecimenBuilder(
new FixedBuilder(instance),
new ExactTypeSpecification(instance.GetType()));
fixture.Customizations.Insert(0, builder);
}
Alternatively you could always invoke the Inject method through a wrapper non-generic method that calls the target method via reflection.
How can I mock a Managed Extensibility Framework (MEF) import into an ExportFactory[IMyType[T]], using mocks of IMyType[T] (being itself a generic interface)? Or, in general, specify instances to be returned by the ExportFactory, which can't be created with a constructor alone?
Moq can't create a mock instance directly, as far as I know. I want an alternative to implementing the whole interface, which may be much larger and change, while I don't want to change the test.
I once found a very complex ExportProvider code, with key-value strings, which didn't work if the generic type of the ExportFactory[T] was itself generic.
Edit:
It turned out that the existing code used contract name strings, generated from type.FullName. This was fine for non-generics, but generics have a different name syntax. The code I worked with, already has a quite complex class, derived from ExportProvider and overriding some original methods, which allows Moq mock.Object instances to be returned by the factory. It's actually always the same instance, not really a factory. See also this question on CodeReview: https://codereview.stackexchange.com/questions/208550/retrieve-generic-contract-names-for-managed-extensibility-framework
// actual generic type is meaningless here, but it is a generic interface
public interface IMyType<T>
{
string GetMessage();
}
public class FactoryImporter<T>
{
[Import]
ExportFactory<IMyType<T>> MyTypeFactory {get;set;}
}
public class Tester
{
public void TestFactoryImporter()
{
Func<IMyType<string>> createMockFunc = () =>
{
var mock = new Mock<IMyType<string>>();
mock.Setup(m => m.GetMessage()).Returns("I'm a mocked IMyType<string>");
return mock.Object;
}
var regBuilder = new RegistrationBuilder();
// pseudo-code, how to do this in reality?
regBuilder.ForType<IMyType<string>>().CreateInstance(createMockFunc);
var catalog = new AggregateCatalog();
var appCatalog = new ApplicationCatalog(regBuilder);
catalog.Catalogs.Add(appCatalog);
var container = new CompositionContainer(catalog);
var factoryImporter = new FactoryImporter<string>();
container.ComposeParts(factoryImporter);
Assert.AreEqual(
"I'm a mocked IMyType<string>",
factoryImporter.MyTypeFactory.GetExport().Value.GetMessage());
}
}
Let's say I have several implementations of an interface:
public interface IDemoInterface
{
void DemoMethod();
}
public class DemoClass1 : IDemoInterface
{
public void DemoMethod()
{
Console.WriteLine("DemoClass1");
}
}
public class DemoClass2 : IDemoInterface
{
public void DemoMethod()
{
Console.WriteLine("DemoClass2");
}
}
Now, I am trying to define an array of such implementations and for each implementation call the interface method. Essentially, do something like this (what follows is a NON-WORKING code -- just an illustration of what I am trying to do):
public static void Run()
{
var demoClasses = { DemoClass1, DemoClass2};
foreach (var demoClass in demoClasses)
{
var implementation = demoClass as IDemoInterface;
implementation.DemoMethod();
}
}
What is the best way to accomplish it? Is using Reflection the only way?
From your example, it looks like you're not trying to loop through instances of classes that implement your interface. You're trying to loop through the types themselves. I'm basing it on this...
var demoClasses = { DemoClass1, DemoClass2};
...and in your question DemoClass and DemoClass2 are class types, not instances of types.
You could start with a collection of types and then create an instance of each type, like this. (You could also use reflection to find the class types that implement your interface.)
var types = new Type[] {typeof(DemoClass1), typeof(DemoClass1)};
foreach (var type in types)
{
if (typeof(IDemoInterface).IsAssignableFrom(type))
{
var instance = Activator.CreateInstance(type) as IDemoInterface;
instance.DemoMethod();
}
}
That will work, but there's a huge limitation: Each class must have a default constructor. Or if you're going to call a constructor, they would all need to have the same one.
In other words, if one of these classes has a constructor like this:
public DemoClass1(string connectionString){
then Activator.CreateInstance will blow up unless you give it the values to pass into the constructor. But if you have an array of types and they have different constructors then it's pretty much impossible to do that. And you don't want to paint yourself into a corner where you have to write classes that can only have empty constructors.
When you have an interface and classes that implement that interfaces, and you want to get instances of those classes, a dependency injection container (Ioc container) can be helpful. If you haven't used it there's a tiny bit of a learning curve, but it's a very useful tool to have in your box. Here's an example (this is from my blog) of configuring a Windsor container to "register", or declare several implementations of an interface.
(If you're not familiar with this it's going to seem totally out of nowhere, which is why I also linked to Windsor's documentation.)
public class DependencyRegistration : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel));
container.Register(Component.For<OrderValidator>());
container.Register(
Component.For<IOrderValidator,AddressValidator>()
.Named("AddressValidator"),
Component.For<IOrderValidator,OrderLinesValidator>()
.Named("OrderLinesValidator"),
Component.For<IOrderValidator,ProductStateRestrictionsValidator>()
.Named("ProductStateRestrictionsValidator")
);
}
}
In this example I've told this "container" that there are three classes that implement IOrderValidator.
Now this container can "resolve", or return, an array of implementations of IOrderValidator. Notice this line near the top:
container.Register(Component.For<OrderValidator>());
Here's that class:
public class OrderValidator : IOrderValidator
{
private readonly IOrderValidator[] _subValidators;
public OrderValidator(IOrderValidator[] subValidators)
{
_subValidators = subValidators;
}
public IEnumerable<ValidationMessage> GetValidationMessages(Order order)
{
var validationMessages = new List<ValidationMessage>();
foreach(var validator in _subValidators)
{
validationMessages.AddRange(validator.GetValidationMessages(order));
}
return validationMessages;
}
}
Notice that in the constructor there is an array of IOrderValidator. If I were to call
var validator = container.Resolve<OrderValidator>();
the container would create an instance of OrderValidator. It would detect that the constructor requires an array of IOrderValidator, so it would create instances of all of those other classes and place them in the array.
If any of those classes also had constructors that required other values or classes, and I told the container how to create those, it would create those as needed in order to be able to create the implementations of IOrderValidator.
The result is that I can have numerous implementations of a class, each with different constructor dependencies of their own, and I can create a collection of those implementations.
This answer doesn't go far toward really telling you how to do this, but hopefully it shows where to find the tools to accomplish this sort of thing. DI containers are very useful tools when used correctly. It's common practice in large applications and even small ones because it makes it easier to manage lots and lots of class types that may be nested inside one another while keeping it sane and understandable. It also helps us to write classes that are smaller and easier to unit test.
In addition to Windsor some other containers are Autofac, Unity, SimpleInjector, and the DI container that's included with ASP.NET Core applications.
Your code is mostly correct:
private static void Main()
{
var demoClasses = new List<IDemoInterface> {new DemoClass1(), new DemoClass2()};
foreach (var demoClass in demoClasses)
{
demoClass.DemoMethod();
}
Console.Write("\nDone!\nPress any key to exit...");
Console.ReadKey();
}
Output
From the question, it is not clear for me if you wish to initialize the types yourself, or if you want to do it like Rufus's answer.
However, if you do not know the implementation beforehand, you could theoretically scan for them, and retrieve all the types
// can throw a ReflectionTypeLoadException in case not all dlls are known
private static IEnumerable<Type> GetImplementationsOf<TInterface>() {
var interfaceType = typeof( TInterface );
return AppDomain.CurrentDomain.GetAssemblies()
.Select( assembly => assembly.GetTypes().Where( type => !type.IsInterface && interfaceType.IsAssignableFrom( type ) ) )
.SelectMany( implementation => implementation );
}
This code will return a IEnumerable<Type> that matches the generic type parameter, and which isn't an interface (though theoretically, this part you could leave for your consumer to handle)
Afterwards, you can run through the list of types and create an instance of them and run your code, like so:
var types = GetImplementationsOf<IDemoInterface>();
foreach (var type in types) {
// will throw an exception in case there is no parameterless constructor
var impl = (IDemoInterface) Activator.CreateInstance( type );
impl.DemoMethod();
}
How do you get around the scenario where the TestFixture you are trying to define needs to reference types that do not have a no-arg constructor?
I'm trying to test an interface that has multiple implementations. From the NUnit documentation it showed how this could be setup with generics like this (where I can define multiple implementation types):
[TestFixture(typeof(Impl1MyInterface))]
[TestFixture(typeof(Impl2MyInterface))]
[TestFixture(typeof(Impl3MyInterface))]
public class TesterOfIMyInterface<T> where T : IMyInterface, new() {
public IMyInterface _impl;
[SetUp]
public void CreateIMyInterfaceImpl() {
_impl = new T();
}
}
The problem arises because Impl1MyInterface, Impl2MyInterface, etc do not have no-arg constructors so when NUnit tries to discover the available test cases I get this error (and the tests do not show up in VS):
Exception System.ArgumentException, Exception thrown discovering tests
in XYZ.dll
Is there a way to work around this? It doesn't make sense to define no-arg constructors because my code needs those values to work.
Instead of using new T() to instantiate your objects, you could use a dependency injection container to instantiate them for you. Here's an example using Microsoft's Unity:
[SetUp]
public void CreateIMyInterfaceImpl() {
var container = new UnityContainer();
// Register the Types that implement the interfaces needed by
// the Type we're testing.
// Ideally for Unit Tests these should be Test Doubles.
container.RegisterType<IDependencyOne, DependencyOneStub>();
container.RegisterType<IDependencyTwo, DependencyTwoMock>();
// Have Unity create an instance of T for us, using all
// the required dependencies we just registered
_impl = container.Resolve<T>();
}
As #Steve Lillis has said in his answer, you need to stop using new T(). When you do this, you don't need to use the new constraint on your generic. One option would be to use an IOC container, like Castle Windsor / Unity as Steve suggested to resolve the dependencies in your Setup.
You haven't said what parameters your implementation's constructors take, but if they're all the same, then an alternate would be to use Activator.CreateInstance instead. So, if your constructors all took an integer and a string, your code would look like this:
[TestFixture(typeof(Impl1MyInterface))]
[TestFixture(typeof(Impl2MyInterface))]
[TestFixture(typeof(Impl3MyInterface))]
public class TesterOfIMyInterface<T> where T : IMyInterface {
public IMyInterface _impl;
[SetUp]
public void CreateIMyInterfaceImpl() {
int someInt1 = 5;
string someString = "some value";
_impl = (T)Activator.CreateInstance(typeof(T), new object[] { someInt1, someString });
}
}
Bear with me, I'm new to NUnit. I come from the land of Rails, so some of this is new to me.
I have a line of code that looks like this:
var code = WebSiteConfiguration.Instance.getCodeByCodeNameAndType("CATALOG_Brands_MinQty", item.Catalog);
I'm trying to mock it, like this (assume code is already initialized):
var _websiteConfigurationMock = new DynamicMock(typeof(WebSiteConfiguration));
_websiteConfigurationMock.ExpectAndReturn("getCodeByCodeNameAndType", code);
When I debug the test, getCodeByCodeNameAndType is returning null, instead of the expected code. What am I doing wrong?
NUnit version: 2.2.8
I'm sorry, but I've never used NUnit.Mocks - but I do have some experience with NMock and Moq [which, by the way, I highly recommend]. Typically, you use a mocking library to generate proxies for Interface definitions, and I presume NUnit.Mocks operates the same way.
Therefore, if you would like to mock your singleton, you will likely have to do the following,
a. Create an interface, say
// All methods you would like to mock from this class, should
// be members of this interface
public interface IWebSiteConfiguration
{
// Should match signature of method you are mocking
CodeType getCodeByCodeNameAndType (
string codeString,
CatalogType catalogType);
}
b. "Implement" interface
// You've already written the method, interface matches signature,
// should be as easy as slapping interface on class declaration
public class WebSiteConfiguration : IWebSiteConfiguration { }
c. Consume interface
alright, so step c. is where most of your work will be. Logically, if you are mocking your singleton, you are actually unit testing the consumer [which you have left out of your sample]. For c. simply add a parameter to the consumer's ctor, or add a publicly accessible property of Type 'IWebSiteConfiguration', and then internally, reference the instance member and invoke your methods against this new interface. Consider this,
was
public class MyClass
{
public MyClass () { }
public void DoSomething ()
{
// bad singleton! bad boy! static references are bad! you
// can't change them! convenient but bad!
code = WebSiteConfiguration.Instance.getCodeByCodeNameAndType (
"some.string",
someCatalog)
}
}
becomes
public class MyClass
{
private readonly IWebSiteConfiguration _config = null;
// just so you don't break any other code, you can default
// to your static singleton on a default ctor
public MyClass () : this (WebSiteConfiguration.Instance) { }
// new constructor permits you to swap in any implementation
// including your mock!
public MyClass (IWebSiteConfiguration config)
{
_config = config;
}
public void DoSomething ()
{
// huzzah!
code = _config.getCodeByCodeNameAndType ("some.string", someCatalog)
}
}
In your unit test, create the mock, pass a reference of the mock to the consumer, and test the consumer.
[Test]
public void Test ()
{
IWebSiteConfiguration mockConfig = null;
// setup mock instance and expectation via
// NUnit.Mocks, NMock, or Moq
MyClass myClass = new MyClass (mockConfig);
myClass.DoSomething ();
// verify results
}
This also serves as a practical introduction to Dependency Injection [DI]. It's simply the practice of passing, or "injecting", references of services [eg your web site configuration class] to the consumer, rather than having the consumer invoke the service directly [eg via static singleton class].
Hope this helps :)
A DynamicMock creates a new object in-memory that represents the interface, or marshallable (inherits from MarshalByRef) class you want to mock.
Try this:
var _websiteConfigurationMock = new DynamicMock(typeof(WebSiteConfiguration));
_websiteConfigurationMock.ExpectAndReturn("getCodeByCodeNameAndType", code);
WebSiteConfiguration conf = (WebSiteConfiguration)_websiteConfigurationMock.MockInstance;
var x = conf.getCodeByCodeNameAndType("CATALOG_Brands_MinQty", item.Catalog);
Note that the third line there will not work unless WebSiteConfiguration inherits from MarshalByRef.
What you typically do is mock an interface and get a new object that implements this interface, but behaves the way you've configured it to do, without having to go and make a concrete type for it, so I'm not entirely sure what you're doing is going to work unless you employ a better isolation framework, like TypeMock that can intercept calls to static methods/properties in existing objects.
Seems there is a kind of solution for this using reflection, or maybe I totally misunderstood this.
It is discussed here:
http://www.geekbeing.com/2010/05/23/how-to-unit-test-singleton-hack-in-c
Could it really works?
public class TestableSingleton : SingletonClass
{
public TestableSingleton ()
{
FieldInfo fieldInfo = typeof(SingletonClass)
.GetField("_instance",
BindingFlags.Static | BindingFlags.NonPublic);
fieldInfo.SetValue(Instance, this);
}
}
Project availabe on https://github.com/rbabreu/TestableSingleton
Actually I could not compile it on Visual Studio since the SingletonClass would have a private constructor. If someone get it to work would be great to avoid the overhead of adapter pattern.