How to call constructor with interface arguments when mocking a concrete class with Moq - class

I have the following class, which uses constructor injection:
public class Service : IService
{
public Service(IRepository repository, IProvider provider) { ... }
}
For most methods in this class, I simply create Moq mocks for IRepository and IProvider and construct the Service. However, there is one method in the class that calls several other methods in the same class. For testing this method, instead of testing all those methods together, I want to test that the method calls those methods correctly and processes their return values correctly.
The best way to do this is to mock Service. I've mocked concrete classes with Moq before without issue. I've even mocked concrete classes that require constructor arguments with Moq without issue. However, this is the first time I've needed to pass mocked arguments into the constructor for a mocked object. Naturally, I tried to do it this way:
var repository = new Mock<IRepository>();
var provider = new Mock<IProvider>();
var service = new Mock<Service>(repository.Object, provider.Object);
However, that does not work. Instead, I get the following error:
Castle.DynamicProxy.InvalidProxyConstructorArgumentsException : Can not instantiate proxy of class: My.Namespace.Service.
Could not find a constructor that would match given arguments:
Castle.Proxies.IRepository
Castle.Proxies.IProvider
This works fine if Service's constructor takes simple arguments like ints and strings, but not if it takes interfaces that I'm mocking. How do you do this?

Why are you mocking the service you are testing? If you are wishing to test the implementation of the Service class (whether that be calls to mocked objects or not), all you need are mocks for the two interfaces, not the test class.
Instead of:
var repository = new Mock<IRepository>();
var provider = new Mock<IProvider>();
var service = new Mock<Service>(repository.Object, provider.Object);
Shouldn't it be this instead?
var repository = new Mock<IRepository>();
var provider = new Mock<IProvider>();
var service = new Service(repository.Object, provider.Object);
I realize that it is possible to mock concrete objects in some frameworks, but what is your intended purpose? The idea behind mocking something is to remove the actual implementation so that it does not influence your test. But in your question, you have stated that you wish to know that certain classes are called on properly, and then you wish to validate the results of those actions. That is undoubtedly testing the implementation, and for that reason, I am having a hard time seeing the goals of mocking the concrete object.

I had a very similar problem when my equivalent of Service had an internal constructor, so it was not visible to Moq.
I added
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
to my AssemblyInfo.cs file for the implementing project. Not sure if it is relevant, but I wanted to add a suggestion on the off chance that it helps you or someone else.

It must be old version issue, all is ok with latest version. Nick, Please check!
P.s.: I started bounty by misstake (I had wrong signature in my constructor).

Related

Mocking vert.x application with PowerMockito

I'm trying to test my verticle but with mocked MongoDB (not to perform real DB actions during the process of unit testing), I've tried to mock my client, but looks like when I use vertx.deployVerticle() my mocks are not being taken into account.
Here's an example of my test setup:
#RunWith(VertxUnitRunner.class)
#PrepareForTest({ MongoClient.class })
public class VerticleTest {
#Rule
public PowerMockRule rule = new PowerMockRule();
private Vertx vertx;
private Integer port;
#Before
public void setUp(TestContext context) throws Exception {
vertx = Vertx.vertx();
mockStatic(MongoClient.class);
MongoClient mongo = Mockito.mock(MongoClientImpl.class);
when(MongoClient.createShared(any(), any())).thenReturn(mongo);
ServerSocket socket = new ServerSocket(0);
port = socket.getLocalPort();
socket.close();
DeploymentOptions options = new DeploymentOptions().setConfig(new JsonObject().put("http.port", port));
vertx.deployVerticle(TalWebVerticle.class.getName(), options, context.asyncAssertSuccess());
}
And what I actually see, that is that MongoClient.createShared is still being called, though I've mocked it.
What can I do in this case?
Edit 1.
Looks like the problem is that MongoClient is an interface and PowerMockito is not able to mock static methods in this case.
I'm still trying to find workaround for this case.
I didn't know that the MongoClient is an interface then I gave my first answer.
PowerMock doesn't supports mocking static calls interfaces (bug #510, Javaassist fixed exception, but mocking static methods still isn't supported). It will be called in next release.
I was focusing on issue in PowerMock, not why it's needed. I agree with answer which was provided in Mailing List.
You could work around it by creating a helper method in your own code
that returns MongoClient.createdShared(). Then in your test, mock that
helper to return your mocked MongoClientImp
But it will be not a work around, but right design solution. Mocking MongoClient is not a good approach, because you should not mock types you don't own.
So better way will be create a custom helper which will create MongoClientfor you and then mock this the helper in unit test. Also you will need integration tests for this helper which will call real MongoClient.createdShared().
If you don't have an opportunity to change code (or you don't want to change code without tests), then I've create an example with work around how PowerMock bug could be bypassed.
Main ideas:
create a custom MainMockTransformer. The transformer will transform interfaces classes to enable supporting mock static calls for interfaces
create a custom PowerMockRunner which will be used to add the custom MockTransformer to transformers chains.
Please, bring to notice on packages name where these new classes are located. It's important. If you want to move them into another packages then you will need to add these new packages to #PowerMockIgnore.

How can I fake a Class used insite SUT using FakeItEasy

Am having a little trouble understanding what and what cannot be done using FakeItEasy. Suppose I have a class
public class ToBeTested{
public bool MethodToBeTested(){
SomeDependentClass dependentClass = new SomeDependentClass();
var result = dependentClass.DoSomething();
if(result) return "Something was true";
return "Something was false";
}
}
And I do something like below to fake the dependent class
var fakedDepClass = A.Fake<DependentClass>();
A.CallTo(fakedDepClass).WithReturnType<bool>().Returns(true);
How can i use this fakedDepClass when am testing MethodToBeTested. If DependentClass was passed as argument, then I can pass my fakedDepClass, but in my case it is not (also this is legacy code that I dont control).
Any ideas?
Thanks
K
Calling new SomeDependentClass() inside MethodToBeTested means that you get a concrete actual SomeDependentClass instance. It's not a fake, and cannot be a FakeItEasy fake.
You have to be able to inject the fake class into the code to be tested, either (as you say) via an argument to MethodToBeTested or perhaps through one of ToBeTested's constructors or properties.
If you can't do that, FakeItEasy will not be able to help you.
If you do not have the ability to change ToBeTested (and I'd ask why you're writing tests for it, but that's an aside), you may need to go with another isolation framework. I have used TypeMock Isolator for just the sort of situation you describe, and it did a good job.

JPA2, JAX-RS: #PersistentContext, How to get EntityManager in a Facade constructor?

I have a JAX-RS web service that was generated by Netbeans. There are non-abstract facade classes for the service's endpoints. The persistence context is being injected into the non-abstract facade. Everything is working well and I see my data being returned to Fiddler.
We are using DTOs and I am implementing an assembler pattern. So, in the non-abstract facade's constructor, I am creating an instance of the assembler, and am passing the facade's entity manager instance into it. Unfortunately, it seems that the injection of the persistence context has not happened before the facade's constructor has been called, so I cannot pass the entity manager instance into the assembler for its to use in mapping operations. Kind of a chicken-before-the-end situation... I cannot figure out how to make this work... Is there some kind of post-constructor method that I can override and perform the initialization of the assembler and pass in the entity manager to it? I'd really appreciate your help and suggestions.
Thank you for your time and ideas,
Mike
Use method marked with #PostConstruct annotation. Like this:
#PostConstruct
private void init() {
// I'm called after all injections have been resolved
// initialize some object variables here
...
}
In that method you can use both, object fields initialized in the constructor and passed by injection.

StructureMap Specifying Explicit Constructor Arguments

I'm working on legacy code.
I have different methods of the same class that pass different arguments to the constructor of a dependency. I'm trying to get some basic IoC usage introduced. Right now I have StructureMap passing my arguments like this:
var thing = ObjectFactory.GetInstance<IThingInterface>(new ExplicitArguments(
new Dictionary<string, object> {
{ "constructorArgA", notShown },
{ "constructorArgB", redacted.Property } }));
Where the actual properties passed for constructorArgA and B change depending on where I am.
Instead of "constructorArgA" is there a way to configure this via actual types, like you can do when configuring the objectFactory, like:
x.For<IHidden>().Use<RealType>()
.Ctor<IConfig>().Is(new Func<IContext, IConfig>(
(context) => someMethodToGetIConfig()));
If I were writing this from scratch I'd probably structure the dependencies a bit different to avoid this, but that's not an option for me right now.
This is something of a classic/common question with DI Containers.
My first choice would be to create a "manual" abstract factory to create IThingInterface, and then use Structuremap to inject IThingInterfaceFactory where it is needed. By manual factory, I mean a class the calls new ThingInterface() and returns it. If you do it this way, your implementation will no longer be container-managed, and if it has dependencies, they would no longer be provided by the container (may or may not be a problem for you).
Second choice would be to create an abstract factory that actually uses/wraps the container. So basically your first code snippet but wrapped in a factory class where the Create() method takes your parameters. This has the advantage of everything (including your implementation and its dependencies) being container-managed, but the disadvantage of referencing your container directly (which is not a best practice--see Article on Composition Roots).
You could also do setter injection, but I would personally consider it a last resort.
Castle Windsor has a good solution to this problem built in (Typed Factory Facility). Not sure if switching containers in an option, but you might consider it.

How to carry out custom initialisation with autofac

I'm adding autofac to an existing project and some of the service implementations require their Initialize method to be called and passed configuration information. Currently I'm using the code:
builder.Register(context =>
{
var service =
new SqlTaxRateProvider(context.Resolve<IUserProvider>());
service.Initialize(config);
return service;
}
).As<ITaxService>()
.SingleInstance();
which works but I'm still creating the object myself which is what I'm trying to get away from this and allow autofac to handle it for me. Is it possible to configure a post create operation that would carry out the custom initialisation?
To give you an idea of what I'm after ideally this would be the code:
builder.RegisterType<SqlTaxRateProvider>()
.As<ITaxService>()
.OnCreated(service=> service.Initialize(config))
.SingleInstance();
Update:
I am using Autofac-2.1.10.754-NET35
.OnActivating(e => e.Instance.Initialize(...))
should do the trick.
You might also investigate the Startable module (see the Startable entry in the Autofac wiki).
Mark's suggestion to do initialisation in the constructor is also a good one. In that case use
.WithParameter(new NamedParameter("config", config))
to merge the config parameter in with the other constructor dependencies.