Guice injection leaking into other tests - junit

I use Guice to instantiate a VocabularyAPI object for one of my unit tests unitTest1(). However, for another test (unitTest2()), I simply use mockito's #Mock annotation to mock an instance of the same class - VocabularyAPI.
I noticed that when I only run unitTest2() - mockito's mock setting for my VocabularyAPI is configured correctly. However, when I run the entire test suite (both unitTest1() and unitTest2()), both the tests are instantiated with the settings from the injector.
How can I limit the scope of the injected object to only inside the test that it is being injected? I want to be able to use the injected object in unitTest1() and mocked object for unitTest2().

Any problems in using local variables?
In unitTest1():
VocabularyAPI vocabularyAPI = // inject (I'm not familiar with Guice)
In unitTest2():
VocabularyAPI vocabularyAPI = Mockito.mock(VocabularyAPI.class);

Related

Mock a particular method in DAO layer in junit

I have an application with rest api endpoints. I want to write test cases for that. It follows MVC architecture. For one of the end points I want to mock a method in my DAO class.
Sample code for my test class is:
RequestBuilder requestGetBuilder = MockMvcRequestBuilders
.get("/processcal/getdata/srn/{srn}",1000)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON);
This controller will call the DAO layer having that method to be mocked.
I tried using the mockito as below in my Test config class:
#Bean
#Primary
BookMarkDao bookMarkDao() {
final BookMarkDao bookMarkDao = Mockito.mock(BookMarkDao.class);
Mockito.when(bookMarkDao.fetchMrPostProcessCalc(Mockito.anyString()))
.thenReturn(TestUtils.getMockResponse());
return bookMarkDao;
}
The problem with this is it's mocking the entire DAO bean so for rest of the endpoints its not calling the DAO class methods and my test coverage reduces. Is there a way around solving this?
You can use a specific profile for mocked beans and activate this profile in necessary test cases. By the way, if your application based on the spring-boot then you can use #MockBean instead of manual making a mock of your DAO in test configurations.

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.

Class loading collision between Robolectric and 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);

Looking for way to replace many "when...thenReturn" statements in test method

I'm writing a JUnit test on a method that is interacting primarily with classes in org.apache.poi.hssf.usermodel (like HSSFWorkbook, HSSFFont and HSSFCellStyle).
The method ultimately builds up and returns an HSSFWorkbook object.
In order to build up the HSSFWorkbook object, methods like workbook.createFont() and workbook.createCellStyle() are invoked.
I currently mock out the objects like this in the setup class of my unit test
workbook = mock(HSSFWorkbook.class);
font = mock(HSSFFont.class);
cellStyle = mock(HSSFCellStyle.class);
Then, in my test method, I invoke the following to avoid NPEs
when(workbook.createFont()).thenReturn(font);
when(workbook.createCellStyle()).thenReturn(cellStyle);
I'm discovering I'll have to do many more of those in order to avoid the NPEs and I'm wondering if there's a way that I can avoid writing all of those "when...thenReturn" statements.
one of the rules of Mocking is: Never mock types you don't own. Another rule is a stubbed call on a mock, shouldn't return another mock.
The reason is in front of you :).
If your class only deals with creating the HSSFWorkbook, then treat the tests as integration tests and use the real library. If your class does something else too, then move all the other stuff to other classes (this is to follow the single responsibility principle)

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...
}