PowerMokito issue with extended methods - powermock

Issue: Cannot stub a method on a return object from an extended class.I just get null pointers on the method I am trying to stub. Do I need to perform a spy first on the objects? I tried that as well and didn't work.
Test Framework:
PowerMockito version 1.9
PowerMock version 1.4.11
EasyMock version 3.1
Line of code attempting to test.
String expected = methodFromExtendedClass_GetObject().getStringValueFromReturnObject();
Test Code
PowerMockito.stub(MemberModifier.method(ExtendedClassA.class, "methodFromExtendedClass_GetObject()")).toReturn(new testObject());
PowerMockito.stub(MemberModifier.method(testObject.class, "getStringValueFromReturnObject")).toReturn(testString);

I dont know the EasyMock syntax, but I do know Mockito. I dont have too much to work with here, but it seems that you are just trying to create a Stubbed Object to return another Mock that returns a string.
If so, Create the Mock test object:
TestObject testObject = mock(TestObject.class);
when(testObject.getStringValueFromReturnObject()).thenReturn(testString);
Then use that Mock as the return for your stub:
PowerMockito.stub(MemberModifier.method(ExtendedClassA.class,
"methodFromExtendedClass_GetObject()")).toReturn(testObject);

Related

Any() method fails to compile in Java 1.8 with Mockito 1.10.9

My below code works well with Java 1.7 and Mockito version is 1.10.19.
#Test
public void populateUsersEmpty() {
// arrange
List<UserDTO> users = new ArrayList<UserDTO>();
// act
requestBuilder.populateUsers(mxsMessageOutMock, users);
// assert
verify(mxsMessageOutMock, times(0)).addRecordSet(CreateNewAlertRequestBuilder.MXS_RECORDSETNAME_USERS);
verify(mxsMessageOutMock, times(0)).addFieldNewRecord(anyString(), anyString());
verify(mxsMessageOutMock, times(0)).addField(anyString(), any());
}
But when I moved to Java 1.8 with same version of Mockito it started showing below error (bold letters). When I checked Mockito website I found that Mockito 3 yet to support java 8. If yes,then what is solution for this? Should I have to wait for their release or Is there any way to fix this. I tried passing AnyString() in place of any() but my code breaks still. Even anyObject() didn't help me.
verify(mxsMessageOutMock, times(0)).addField(anyString(), anyString());
CreateNewAlertRequestBuilderTest.java:436:0::0 The method addField(String, String) is ambiguous for the type IMXSMessageOut
[ant:iajc] [error 7]: error at verify(mockMessageOut, times(0)).addField(anyString(), any());
I understand that Its difficult to suggest without full code but here what I could share piece of code.
any(String.class)? if addField is accepting String, String why don't u use anyString(), anyString()

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.

Schedule Expression

I am trying to create a Junit test for a method which includes ScheduleExpression. I have tried to use PowerMockito to mock it but I continue to get a error message which reads
java.lang.ClassFormatError: Absent Code attribute in method
that is not native or abstract in class file javax/ejb/ScheduleExpression
Here is how I am using PowerMockito
ScheduleExpression expression = PowerMockito.mock(ScheduleExpression.class);
I have tried the annotations
#RunWith(PowerMockRunner.class)
#PrepareForTest(Static.class)
but they didn't work.
I have also tried Mockito version 1.9.5 but I get the same error. Am I missing a pom dependency?
Is there a way to Mock the ScheduleExpression?
You have to use the name of the class you want PowerMock to prepare for...
#PrepareForTest(ScheduleExpression.class)
However, in your case I don't see the need to use PowerMock because ScheduleExpression is not final, or has private or static methods you may be trying to mock.
Try just using vanilla Mockito instead of PowerMockito like this...
#RunWith(MockitoJUnitRunner.class)
...
ScheduleExpression expression = Mockito.mock(ScheduleExpression.class);

How to test a void method with JMock

How to test a void method i.e. method that doesn't return anything in JMock?
To test a method that doesn't return anything, regardless of the testing or mocking framework you're using, you test the effect of a call to the method.
With JMock that likely means that you create a mock of something the code you're testing should call, set things up so that your mock is used instead of a real object, and set and verify expectations for calls to that mock.
I might be able to get more specific if you can add specifics to your question.
void methods generally make some changes in the value of the fields of the class. If the field of the class is not private then you can access it in your test class after calling the void method in your test method to assert if you are getting the expected value.

How do I unit test a Grails service that uses a converter?

I have a Grails service that sends out e-mails using a 3rd-party service by doing a HTTP call:
class EmailService {
def sendEmail(values) {
def valueJson = values as JSON
... // does HTTP call to 3rd party service
}
}
I've written a unit test to test this service (because an integration test spins up Hibernate and the entire domain framework, which I don't need):
#TestFor(EmailService)
class EmailServiceTests {
void testEmailServiceWorks() {
def values = [test: 'test', test2: 'test2']
service.sendEmail(values)
}
}
However, when I execute this unit test, it fails with this exception when it tries to do the as JSON conversion:
org.apache.commons.lang.UnhandledException: org.codehaus.groovy.grails.web.converters.exceptions.ConverterException: Unconvertable Object of class: java.util.LinkedHashMap
I then re-wrote my unit test to just do the following:
void testEmailServiceWorks() {
def value = [test: 'test', test2: 'test2']
def valueJson = value as JSON
}
And I get the same exception when it tries to do the as JSON conversion.
Does anyone know why I'm getting this exception, and how I can fix it?
Even though you are testing a service, you can apply the #TestMixin(ControllerUnitTestMixin) annotation to your test class to get Grails to set up the JSON converter.
The as JSON magic is created when the domain framework spins up.
You have to either change your test to an integration one or mock the asType.
def setUp(){
java.util.LinkedHashMap.metaClass.asType = { Class c ->
new grails.converters."$c"(delegate)
}
}
Rember to clean up after yourself in the tearDown, you wouldn't want metaprogramming leaks in your test suite.
def tearDown(){
java.util.LinkedHashMap.metaClass.asType = null
}
Edit:
If you come from the future, consider this answer: https://stackoverflow.com/a/15485593/194932
As Grails 3.3.x grails-test-mixins plugin is deprecated. #see migration guide.
For this problem you should implement GrailsWebUnitTest which is coming from Grails Testing Support Framework.
you can initialise the JSON in the setUp() . There are various marshallers which implement ObjectMarshaller , which need to be added to the ConverterConfiguration for JSON conversion to work.
http://grails.github.io/grails-doc/2.4.4/api/index.html?org/codehaus/groovy/grails/web/converters/marshaller/json/package-summary.html
example :
DefaultConverterConfiguration<JSON> defaultConverterConfig = new DefaultConverterConfiguration<JSON>()
defaultConverterConfig.registerObjectMarshaller(new CollectionMarshaller())
defaultConverterConfig.registerObjectMarshaller(new MapMarshaller())
defaultConverterConfig.registerObjectMarshaller(new GenericJavaBeanMarshaller())
ConvertersConfigurationHolder.setTheadLocalConverterConfiguration(JSON.class, defaultConverterConfig);
I just ran into this, and I really didn't want to implement GrailsWebUnitTest as recommended in another answer here. I want to keep my service test as "pure" and lean as possible. I ended up doing this:
void setupSpec() {
defineBeans(new ConvertersGrailsPlugin())
}
void cleanupSpec() {
ConvertersConfigurationHolder.clear()
}
This is how it happens under the hood when you implement GrailsWebUnitTest (via WebSetupSpecInterceptor and WebCleanupSpecInterceptor).
That said, the converters seem to be meant for use in the web tier, primarily for making it easy to transparently return data in different formats from a controller. It's worth considering why the service you're testing needs the converters in the first place.
For example, in my case, someone used the JSON converter to serialize some data to a string so it could be stored in a single field in the database. That doesn't seem like an appropriate user of the converters, so I plan on changing how it's done. Making the converters available in my service test is a temporary solution to allow me to improve our test coverage before I refactor things.
I was getting the same error when trying to unit test a controller that calls "render myMap as JSON". We use Grails 1.3.7 and none of the other solutions worked for me without introducing other problems. Upgrading Grails was not an alternative for us at the moment.
My solution was to use JSONBuilder instead of "as JSON", like this:
render(contentType: "application/json", {myMap})
See http://docs.grails.org/latest/guide/theWebLayer.html#moreOnJSONBuilder
(I realize this is old, but came here in search for a solution and so might others)