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.
Related
I'm using vertx in my project nad I guess that I had a terrible idea when I create a Java class like this
public class MyClass {
static Vertx vertx = Vertx.vertx();
public void run() {
vertx.getOrCreateContext().runOnContext(event -> {
// run something
});
}
}
Everything I run in this run() function will be run asynchronous but I'm not sure that it's recommended.
Well, if you have a vert.x application, you can get the Vertx object in a class by extending the AbstractVerticle and getting the vert.x object from it using the getVertx() method.
Also, Vertx.vertx() always creates a new instance. It's better to use something like Vertx.currentContext().getOwner()
Remember that static objects are created before non-static objects and non-static methods being run. This means that if there are some configs/checks that needs to be done at bootstrap (for example metrics), they could be missed, unless maybe also done in a static context.
I would advice against doing this. The reason is, that it would heaviliy reduce your ability to write tests for all the classes that rely on that static Vertx instance.
Use dependency injection instead (or use Verticles as described in the other answer).
I'm trying to get dependencies set up correctly in my Workflow application. It seems the best way to do this is using the Service Locator pattern that is provided by Workflow's WorkflowExtensions.
My workflow uses two repositories: IAssetRepository and ISenderRepository. Both have implementations using Entity Framework: EFAssetRepository, and EFSenderRepository, but I'd like both to use the same DbContext.
I'm having trouble getting both to use the same DbContext. I'm used to using IoC for dependency injection, so I thought I'd have to inject the DbContext into the EF repositories via their constructor, but this seems like it would be mixing the service locator and IoC pattern, and I couldn't find an easy way to achieve it, so I don't think this is the way forward.
I guess I need to chain the service locator calls? So that the constructor of my EF repositories do something like this:
public class EFAssetRepository
{
private MyEntities entities;
public EFAssetRepository()
{
this.entities = ActivityContext.GetExtension<MyEntities>();
}
}
Obviously the above won't work because the reference to ActivityContext is made up.
How can I achieve some form of dependency chain using the service locator pattern provided for WF?
Thanks,
Nick
EDIT
I've posted a workaround for my issue below, but I'm still not happy with it. I want the code activity to be able to call metadata.Require<>(), because it should be ignorant of how extensions are loaded, it should just expect that they are. As it is, my metadata.Require<> call will stop the workflow because the extension appears to not be loaded.
It seems one way to do this is by implementing IWorkflowInstanceExtension on an extension class, to turn it into a sort of composite extension. Using this method, I can solve my problem thus:
public class UnitOfWorkExtension : IWorkflowInstanceExtension, IUnitOfWork
{
private MyEntities entities = new MyEntities();
IEnumerable<object> IWorkflowInstanceExtension.GetAdditionalExtensions()
{
return new object[] { new EFAssetRepository(this.entities), new EFSenderRepository(this.entities) };
}
void IWorkflowInstanceExtension.SetInstance(WorkflowInstanceProxy instance) { }
public void SaveChanges()
{
this.entities.SaveChanges();
}
}
The biggest downside to doing it this way is that you can't call metadata.RequireExtension<IAssetRepository>() or metadata.RequireExtension<ISenderRepository>() in the CacheMetadata method of a CodeActivity, which is common practice. Instead, you must call metadata.RequireExtension<IUnitOfWork>(), but it is still fine to do context.GetExtension<IAssetRepository>() in the Execute() method of the CodeActivity. I imagine this is because the CacheMetadata method is called before any workflow instances are created, and if no workflow instances are created, the extension factory won't have been called, and therefore the additional extensions won't have been loaded into the WorkflowInstanceExtensionManager, so essentially, it won't know about the additional extensions until a workflow instance is created.
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).
I designed a new project using Guice/Gin so I could make our code more modular and swap-able especially when testing.
However, I am not able to find out how to make this work in practice. I was under the impression that I could just create a new Gin/Guice module in my test and install my 'base' module, overloading any bindings that I want to replace with specific testing implementations.
I don't want to have to use GWTTestCase and load my entire module, because it is very slow and unecissary for the types of granular testing I need to do.
I have tried using Jukito (http://code.google.com/p/jukito/), gwt-test-utils (http://code.google.com/p/gwt-test-utils/wiki/HowToUseWithGIN) and also some resources on doing this with guice (http://fabiostrozzi.eu/2011/03/27/junit-tests-easy-guice/).
None of these methods are yielding any results.
I think the Guice approach might work, if I defined a mirror guice module for my Gin module. However I really don't want to have to manage both of these. I really just want to test my GIN module like I would assume people test with Guice.
I feel like this should be really simple, can anyone point me to examples that work?
Update
Another way of looking at this question is:
How do I get the examples on the Jukito site (http://code.google.com/p/jukito/) work when the classes I am injecting are in an exernal Gin module?
**Update - In reference to Thomas Boyer's answer **
Thanks for the hint Tom, I was not able to find examples of using the adapter but I tried augmenting the Jukito examples to use the GinModuleAdapter anyway:
#RunWith(JukitoRunner.class)
public class MyGinTest {
public static class Module extends JukitoModule {
protected void configureTest() {
install(new GinModuleAdapter(new ClientModule()));
}
}
#Test
#Inject
public void testAdd(SyncedDOMModel mod){
assertNotNull(mod);
}
}
When I tried to run this test I recieved this exception:
java.lang.AssertionError: should never be actually called
at com.google.gwt.inject.rebind.adapter.GwtDotCreateProvider.get(GwtDotCreateProvider.java:43)
at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:40)
at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1031)
at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
at com.google.inject.Scopes$1$1.get(Scopes.java:65)
at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:40)
at com.google.inject.internal.InternalInjectorCreator$1.call(InternalInjectorCreator.java:204)
at com.google.inject.internal.InternalInjectorCreator$1.call(InternalInjectorCreator.java:198)
at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1024)
at com.google.inject.internal.InternalInjectorCreator.loadEagerSingletons(InternalInjectorCreator.java:198)
at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:179)
at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:109)
at com.google.inject.Guice.createInjector(Guice.java:95)
at com.google.inject.Guice.createInjector(Guice.java:72)
at com.google.inject.Guice.createInjector(Guice.java:62)
at org.jukito.JukitoRunner.ensureInjector(JukitoRunner.java:118)
at org.jukito.JukitoRunner.computeTestMethods(JukitoRunner.java:177)
at org.jukito.JukitoRunner.validateInstanceMethods(JukitoRunner.java:276)
at org.junit.runners.BlockJUnit4ClassRunner.collectInitializationErrors(BlockJUnit4ClassRunner.java:102)
at org.junit.runners.ParentRunner.validate(ParentRunner.java:344)
at org.junit.runners.ParentRunner.<init>(ParentRunner.java:74)
at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:55)
at org.jukito.JukitoRunner.<init>(JukitoRunner.java:72)
My gin module is part of a GWTP project, and looks like this:
public class ClientModule extends AbstractPresenterModule {
#Override
protected void configure() {
install(new DefaultModule(ClientPlaceManager.class));
bindPresenter(MainPagePresenter.class, MainPagePresenter.MyView.class,
MainPageView.class, MainPagePresenter.MyProxy.class);
bindConstant().annotatedWith(DefaultPlace.class).to(NameTokens.main);
bindPresenterWidget(MapTreePresenter.class,
MapTreePresenter.MyView.class, MapTreeView.class);
bindPresenterWidget(MapTreeItemPresenter.class,
MapTreeItemPresenter.MyView.class, MapTreeItemView.class);
bind(ResourcePool.class).to(DefferredResourcePool.class);
bind(WebSocket.class).to(WebSocketImpl.class);
}
}
As you can somewhat see, the class I am injecting in my test SyncedDOMModel, uses a WebSocket which I bind in my module. When I am testing, I don't want to use a real websocket and server. So I want to overload that binding in my test, with a class that basically emulates the whole thing. It's easier to just inject a different implementation of the WebSocket in this case rather than use mocking.
If it helps, this is a basic outline of the SyncedDOMMOdel class:
public class SyncedDOMMOdel {
....
#Inject
public SyncedDOMModel(WebSocket socket){
this.socket = socket;
}
....
}
You can use the GinModuleAdapter to use any GinModule as a Guice Module.
Obviously, you won't benefit from GIN's specific features: default to GWT.create() when something has no particular binding (this includes interfaces and abstract classes, which would throw in Guice), and automatically search for a RemoteService interface when an interface whose name ends Async has no specific binding.
And you won't be able to use anything that depends on JSNI or deferred binding (GWT.create()), as in any non-GWTTestCase unit test.
Recently I was looking at some source code provided by community leaders in their open source implementations. One these projects made use of IOC. Here is sample hypothetical code:
public class Class1
{
private ISomeInterface _someObject;
public Class1(ISomeInterface someObject)
{
_someObject = someObject;
}
// some more code and then
var someOtherObject = new SomeOtherObject();
}
My question is not about what the IOCs are for and how to use them in technical terms but rather what are the guidelines regarding object creation. All that effort and then this line using "new" operator. I don't quite understand. Which object should be created by IOC and for which ones it is permissible to be created via the new operator?
As a general rule of thumb, if something is providing a service which may want to be replaced either for testing or to use a different implementation (e.g. different authentication services) then inject the dependency. If it's something like a collection, or a simple data object which isn't providing behaviour which you'd ever want to vary, then it's fine to instantiate it within the class.
Usually you use IoC because:
A dependency that can change in the future
To code against interfaces, not concrete types
To enable mocking these dependencies in Unit Testing scenarios
You could avoid using IoC in the case where you don't control the dependency, for example an StringBuilder is always going to be an StringBuilder and have a defined behavior, and you usually don't really need to mock that; while you might want to mock an HttpRequestBase, because it's an external dependency on having an internet connection, for example, which is a problem during unit tests (longer execution times, and it's something out of your control).
The same happens for database access repositories and so on.