Class loading collision between Robolectric and Powermock - powermock

I'm trying to write a test that needs both Robolectric 2.2 and PowerMock, as the code under test depends on some Android libraries and third party libraries with final classes that I need to mock.
Given that I'm forced to use the Robolectric test runner through:
#RunWith(RobolectricTestRunner.class)
...I cannot use the PowerMock test runner, so I'm trying to go with the PowerMock java agent alternative, without luck so far.
I have setup everything according to this guide but I'm facing a collision problem between classes required by the javaagent library and by robolectric through its dependency with asm-1.4. Both depend on
org.objectweb.asm.ClassVisitor
, but javaagent-1.5.1 ships with its own version where ClassVisitor is an interface while asm-1.4 version for the same namespace is an abstract class, with the corresponding error at runtime:
java.lang.IncompatibleClassChangeError: class org.objectweb.asm.tree.ClassNode has interface org.objectweb.asm.ClassVisitor as super class
I have even tried to modify the javaagent library jar to entirely remove the org.objectew.asm classes in there, but that doesn't work as ClassNotFoundException happens afterwards due to some other classes needed in the org.objectweb.asm package that only ship in the javaagent library jar, and not in the asm one.
Any ideas? According to examples out there the agent seems to work fine with, at least, the Spring test runner.

I had the same problem and while I didn't solve this problem as such, I wanted to share my approach, which removes the need for PowerMock (which is always a good thing in my view): I wanted to mock a call to
Fragment fooFragment = new FooFragment();
So what I did was addanother level of indirection. I created a FragmentProvider class:
public FragmentFactory fragmentFactory = new FragmentFactory();
[...]
Fragment fooFragment = fragmentFactory.getFooFragment();
After i did this, I could just mock out the factory with standard Mockito, like this:
FragmentFactory mockFactory = mock(FragmentFactory.class);
activity.fragmentFactory = mockFactory;
when(mockFactory.getFooFragment()).thenReturn(mockFooFragment);

Related

Mockito Mocks Behaving Like Spies: Kotlin

I'm working on a kotlin jar in which I am attempting to mock an input to a function
class MyService
fun serviceFunction(input: ClassFromAnotherLibrary): Output {
val foo = input.memberFunction()
It just so happens that memberFunction has been added to that class in my package via an package-level extension function
fun ClassFromAnotherLibrary.memberFunction() : Foo {
val mapper = jacksonObjectMapper()
return mapper.readValue(this.serializedFoo, Foo::class.java)
}
Now I want to write a test for the serviceFunction, but I want to mock out the memberFunction call (I have separate tests for that).
So in my Mockito JUnit test, I do the following
val service = Service()
val mockClassFromAnotherLibrary = mock<ClassFromAnotherLibrary>()
val mockFoo = mock<Foo>()
whenever(mockClassFromAnotherLibrary.memberFunction())
.thenReturn(mockFoo)
service.serviceFunction(mockClassFromAnotherLibrary)
I would expect that memberFunction's actual implementation would never get called, and that my mock would intercept any attempts to call it and instead return my mockFoo.
What's actually happening is the whenever setup to mock out the method is invoking the underlying function, causing a NullPointerException when the mapper tries to read serializedFoo (which is of course null).
My question is: why on earth is the real memberFunction being executed?? I'm new to Mockito and Kotlin, but have used Jasmine (for JS) and Spock (for Groovy / Java) testing in the past, and mocking out an object in both of those frameworks would never actually execute any mocked-out function (that I'm aware of).
I've been able to work around issues similar to this in the past by making the ClassFromAnotherLibrary I'm trying to mock have an interface that I mock instead, but that
Feels hacky, and
Isn't an option in this case (it's not my class to edit, it's coming from another library)
For reference, these are the relevant gradle dependencies my project is using:
compile "com.fasterxml.jackson.module:jackson-module-kotlin:2.8.9"
compile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.8.9"
compile "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.8.9"
testCompile 'junit:junit:4.12'
testCompile "org.jetbrains.kotlin:kotlin-test:1.1.4-3"
testCompile "org.jetbrains.kotlin:kotlin-test-junit:1.1.4-3"
testCompile "com.nhaarman:mockito-kotlin:1.3.0"
testCompile "org.mockito:mockito-inline:2.8.47"
I also have set up a MockMaker file in my test/resources folder to enable mock-maker-inline, though I don't totally understand what it is that might accomplish (saw a tip about it here)
Thanks to any Kotlin/Mockito
Extension functions are nothing but a regular Java static method and as far as I remember, Mockito cannot mock static methods.

Junit test case with Mockito

I am creating junit test cases for my project. I have the below code, where I would like to create a mock,
String propertyFilePath = System.getProperty("path.to.properties");
Resource propertyFile = new FileSystemResourceLoader().getResource(propertyFilePath);
Properties properties = PropertiesLoaderUtils.loadProperties(propertyFile);
I am using junit and mockito-core jar. I tried with below code,
System.setProperty("path.to.properties", "dummyPathToProperties"); //invalid Path
Properties properties = mock(Properties.class);
Resource propertyFile = new FileSystemResourceLoader().getResource("dummyPathToProperties");
when(PropertiesLoaderUtils.loadProperties(propertyFile)).thenReturn(properties);
With above code it throws error when mocking loadProperties method. How can I mock a spring static class and return my mock properties object ?
Any help will be really appreciated.
Mocking static methods requires you to go down the full nine yards and make use of PowerMock. The exact steps to mock static methods are outlined in their documentation for example.
In essence:
Use the #RunWith(PowerMockRunner.class) annotation at the class-level of the test case.
Use the #PrepareForTest(ClassThatContainsStaticMethod.class) annotation at the class-level of the test case.
Use PowerMock.mockStatic(ClassThatContainsStaticMethod.class) to mock all methods of this class.
Use PowerMock.replay(ClassThatContainsStaticMethod.class) to change the class to replay mode.
Use PowerMock.verify(ClassThatContainsStaticMethod.class) to change the class to verify mode.
But of course: consider not using PowerMock; by changing your code so that you don't have to mock the static call. But of course, it is kinda weird to add a wrapper around such a framework-provided static method.

guice return set of instances with custom annotation

I have very simple scenario where class A registers instances for types.
A.register(T1.class, new H1());
A.register(T2.class, new H2());
this is fairly simple configuration when done by hand but guice injection doesn't work when I create instances outside the guice framework.
I try to figure out how to create and configure A with all instance with custom annotation using guice.
I have found something like this Scan the classpath for classes with custom annotation but it is not using guice.
thanks
so I guess code.google.com/p/google-guice/wiki/Multibindings is the only option so far that works, but it is not as nice as I would expect since you need to connect everything by hand.

How to jmock Final class

I was trying to mock final class(AnyFinalClass.java) in junit using JDave in eclipse.
public void setUp() throws Exception {
Mockery mockery = new Mockery() {{
setImposteriser(ClassImposteriser.INSTANCE);
}};
AnyFinalClass any = mockery.mock(AnyFinalClass.class);
}
I am trying to use jdave-unfinalizer-1.1.jar as javaagent but didnt had any success. I tried multiple things but getting following exception
java.lang.IllegalArgumentException: Cannot subclass final class class AnyFinalClass
at net.sf.cglib.proxy.Enhancer.generateClass(Enhancer.java:446)
at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
Can someone who has already tried jdave unfinalizer give me exact step how to make it work on eclipse.
I set following in eclipse.ini file but got the problem
-Xbootclasspath/a:lC:\WS\JunitTesting\jars\asm-3.0.jar
-javaagent:C:\WS\JunitTesting\jars\jdave-unfinalizer-1.1.jar
While running executing the junit, I gave vm argument as
javaagent:C:\WS\JunitTesting\jars\jdave-unfinalizer-1.1.jar
I am not sure what will be the code. jdave is not having the code and its site is pointing to some other site which is not working. Please correct my code or provide your same working code.
Any help is highly appreciated.
from Enhancer.java line 446:
if (TypeUtils.isFinal(sc.getModifiers()))
throw new IllegalArgumentException("Cannot subclass final class " + sc);
I have not worked with JDave but with another mocking frameworks and the only one that allows to mock a final class was powermock
Look also here
In order to get unfinalizer running you have to put -javaagent:path_to_unfinalizer/jdave-unfinalizer-1.1.jar in the VM arguments of the run configuration of the test.
I also had to include several dependencies of jdave-unfinalizer in the classpath of the project from which the tests ar being launched. These are, taken from the maven definitions of jdave:
jdave-core 1.1
cglib-nodep 2.1_3
objenesis 1.0
asm 3.0
asm-commons 3.0
asm-tree 3.0

mock cdi interceptors during junit tests

I have a complex Java EE 6 app with a web module, an EJB module and some utility jars.
I want to do some integration tests with Junit. Therefore I use the openwebbeans cdi container (Thanks to Mr. Struberg http://struberg.wordpress.com/2012/03/17/controlling-cdi-containers-in-se-and-ee/)
It works perfectly. I can start a complete cdi container in a Junit test.
My problem is that I have some interceptors in my application which cannot run in a Junit test (MQ-, persistence- and transaction-interceptors). So I want to mock these interceptor implementations.
Does anybody know how to do this?
To whom it may concern ;-)
At the end I solved my issue with clean Java EE techniques. I provided a method which observes the ProcessAnnotatedType event. This method evaluates the type which is processed and if it is one of my interceptors, then I veto the processing.
public void processAnnotatedType(#Observes final ProcessAnnotatedType<?> event, final BeanManager manager) {
if (event.getAnnotatedType().getJavaClass().equals(PrivilegeCheckingInterceptor.class)) {
event.veto();
}
}
Why not just test in the container of choice with Arquillian? The other option which comes to mind would be to add in interceptors with mock functionality and exclude the actual interceptor implementation when you start the CDI container.
You can also run tests with embedded OpenEJB.
This link http://openejb.apache.org/examples-trunk/interceptors/ may be useful - perhaps setting property of 'openejb.deployments.classpath.exclude' could help.
Another option of "vetoing" could be through Deltaspike #Exclude annotation. It can veto beans based on ProjectStage.
Example:
#Exclude(ifProjectStage = ProjectStage.UnitTest.class)
public class MyInterceptor {
}
Then in your test you can activate the project stage using Deltapike test control module, example:
#RunWith(CdiTestRunner.class)
#TestControl(projectStage = UnitTest.class)
public class TestStageControl {
#Test...
}