Mockito Mocking any I18n instance created runtime - java

I have a scenario ,like i am creating i18n object instance dynamically in code. I am using the following code:
public String getLocaleString(Locale locale, SlingHttpServletRequest request){
final ResourceBundle bundle = request.getResourceBundle(locale);
I18n i18n = new I18n(bundle);
return i18n.get("local");
}
Here locale, request I have mocked. But i18n is created dynamically. so am not able to mock i18n.get("local").
I tried using:
when(any(I18n.class).get("local")).thenReturn("localizedString")
But I am not able to. I am getting NullPointerException in this line.
I would like to use Mockito for mocking this scenario. Can you guys help me please? Thanks.

Mockito has suggesting refactoring to get around this https://code.google.com/p/mockito/wiki/MockingObjectCreation?ts=1332544670&updated=MockingObjectCreation
I normally avoid testing internals of the method.
But in some cases when I really need I use PowerMockito https://code.google.com/p/powermock/wiki/MockConstructor

I don't think it's possible to use any() in that way, as it's an argument matcher, you should only specify a mock object with a method invocation, e.g.:
when(mock(i18n).get("local")).thenReturn("localizedString");
I think that might be the source of your NullPointerException.
But to solve your problem, I think you have two options:
The first is to use a factory to create the I18n object, and then mock the factory:
...
private I18nFactory factory;
...
public String getLocaleString(Locale locale, SlingHttpServletRequest request){
final ResourceBundle bundle = request.getResourceBundle(locale);
I18n i18n = factory.get(bundle);
return i18n.get("local");
}
Then in your test, set up the factory to produce the object you want:
// Mock I18n, locale, request etc...
final I18nFactory factory = mock(I18nFactory.class);
when(factory.get(bundle)).thenReturn(i81n);
// Assign 'factory' to your Controller(?)
controller.setI18nFactory(factory);
// act, assert etc...
The second approach is to set up the locale and request mocks/objects in such a way that new I18n(...) creates a valid object which meets your expectations.
On balance, I think I would prefer to use the second approach, especially so if I18n is a 3rd-party class. Although without more information on the aim of your test, this answer is somewhat speculative. Anyway, I hope this helps.

Related

How to pass param to mocked class method?

I am using mockito to test mu jdk11-springboot application.
My application has class 'ClientRepository' and that has a method called 'findById' which takes a param of type UUID.
SO the method looks like :
public String findById(UUID id)
Now I mocked the class to test as :
#MockBean
private ClientRepository clientRepo;
Now I am trying to figure out how to pass the UUID param here:
Mockito.when(clientRepo.findById(UUID id))
.thenReturn(dslContext.selectFrom(CLIENT).where(CLIENT.ID.eq(UUID.fromString("3e064b19-ef76-4aea-bf82-e9d8d01daf1c"))).fetch());
Can anyone help?
You can use the following construction:
UUID expected = ...;
Mockito.when(clientRepo.findById(Mockito.eq(expected))).thenReturn(...);
This can be a good solution if the expected UUID is not the same instance that you configure in the test.
Another point to consider:
You seem to use JOOQ but have a mock bean for repository, which means that you probably test some kind of service (business logic layer).
In this case maybe you don’t need to work with database at all, just create a string and return in thenReturn part of the mocking configuration
Mockito.when(clientRepo.findById(Mockito.any(UUID.class))
.thenReturn(dslContext.selectFrom(CLIENT).where(CLIENT.ID.eq(UUID.fromString("3e064b19-ef76-4aea-bf82-e9d8d01daf1c"))).fetch());
Use Mockito.eq("your-uuid-goes-here") instead if your mock should only react to specific values.
Passing the value directly for which the mock is expected to return should also work.
Mockito.when(clientRepo.findById(<expected UUID>)
.thenReturn(dslContext.selectFrom(CLIENT).where(CLIENT.ID.eq(UUID.fromString("3e064b19-ef76-4aea-bf82-e9d8d01daf1c"))).fetch());

How is Spring's DataBinder used to convert a plain parameter value?

I've been digging through the Spring DataBinder code and docs while answering this question and i've noticed the DataBinder constructor docs mentionioning :
target - the target object to bind onto (or null if the binder is just
used to convert a plain parameter value)
I've been searching around and haven't found such a usage and it really made me curious. Would appreciate any insight related to :
How would such a data binder be used with a null target to convert a plain parameter value?
Or what does it actually mean to convert a plain parameter value in this context?
Is it also applicable to Spring MVC? (since i noticed it mentioned in WebDataBinder's constructor docs as well).
I have been done some digging in the Spring Framework source, searching for usages with null parameter as you described. Since I was not aware of this kind of usage either, looking at the testcases to understand things better was my way to go.
The test class for DataBinder is (not surprisingly) DataBinderTests.
I am going to paste a usage example here, along with the link to github where I found the code, for reference:
For your first question, the answer seems if you use a DataBinder with null constructor parameter, it means that you just want to use the conversion facility, without the data binding mechanism (since we have not passed an object to bind values to).
This pretty explanatory testcase shows this type of usage, creating a DataBinder with null, setting a DefaultFormattingConversionService to the dataBinder and registering a custom editor after that.
You can add a custom converter with the addConverter method if you want a different String representation after converting your bean.
#Test
public void testConversionWithInappropriateStringEditor() {
DataBinder dataBinder = new DataBinder(null);
DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
dataBinder.setConversionService(conversionService);
dataBinder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
NameBean bean = new NameBean("Fred");
assertEquals("ConversionService should have invoked toString()", "Fred", dataBinder.convertIfNecessary(bean, String.class));
conversionService.addConverter(new NameBeanConverter());
assertEquals("Type converter should have been used", "[Fred]", dataBinder.convertIfNecessary(bean, String.class));
}
For reference, here is the code of NameBeanConverter (also from the test class)
public static class NameBeanConverter implements Converter<NameBean, String> {
#Override
public String convert(NameBean source) {
return "[" + source.getName() + "]";
}
}
Source: https://github.com/spring-projects/spring-framework/blob/d5ee787e1e6653257720afe31ee3f8819cd4605c/spring-context/src/test/java/org/springframework/validation/DataBinderTests.java#L598-L609
I think the above explanation was an answer for the first two questions:
How would such a data binder be used with a null target to convert a plain parameter value?
Or what does it actually mean to convert a plain parameter value in this context?
For your third question, unfortunately, I have not found any usable testcase like above, but going through the WebDataBinder's code make me think of there is no "added value" compared to DataBinder in terms of a null constructor parameter, so you can use the conversion facility through the WebDataBinder as well.
You probably know that you can bind your web request fields to your backing bean, adding conversion (e.g. converting a particularly formatted date to an actual Date field object on the backing bean) etc etc, but I don't want to describe this in more detail as this was not your point with the question I guess.
Lastly, I found this article very useful about how the WebDataBinder could be used: http://www.intertech.com/Blog/spring-frameworks-webdatabinder/
You can think of DataBinder as filter or handler that all request parameters go thorough before they get consumed. To make use of the DataBinder functionality you need to implement a method in your controller class with "#InitBinder" annotation. For example:
#InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
// bind empty strings as null
binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
}
As you see, all you need to do in the method is register CustomEditor for a specific data type.
In Spring MVC, a DataBinder with a null target is automatically used in a case like this :
#RequestMapping(method = RequestMethod.GET)
public String showHome(#RequestParam("date") Date date) {
return "home";
}
In this case, the created DataBinder has an objectName "date" and a null target.

How do I set a property on a mocked object using Mockito?

I have a scenario where I have to set a property of a mocked object as follows:
SlingHttpRequest slingHttpRequest= mock(SlingHttpRequest);
slingHttpRequest.setAttribute("search", someObject);
When I try to print this attribute I get null. How do I set this property?
You don't normally set properties on your mocked objects; instead, you do some specific thing when it's invoked.
when(slingHttpRequest.getAttribute("search")).thenReturn(someObject);
I'm afraid you're misusing your mock SlingHttpRequest.
Mockito requires you to wire up your mock's properties before you use them in your test scenarios, i.e.:
Mockito.when(slingHttpRequest.getAttribute("search")).thenReturn(new Attribute());
You cannot call the setAttribute(final Attribute a) method during the test like so:
slingHttpRequest.setAttribute(someObject);
If you do this, when the test runs, getAttribute() will return null.
Incidently, if the code you are unit testing is going to call a setter on your mock in this way, do not use a mock. Use a stub.
Mock object is not where you store data, it's for you to teach the behavior when its methods are invoked.
try this: https://www.google.com/search?q=mockito+example&oq=mockito+example&aqs=chrome..69i57j0l5.6790j0j7&sourceid=chrome&espv=210&es_sm=93&ie=UTF-8
I'm probable 7 years late for the party, but I still would like to contribute.
You CAN set class property using the Whitebox from powermock:
Whitebox.setInternalState(mockedClass, "internalField", "Value to be returned")

Mockito: Trying to spy on method is calling the original method

I'm using Mockito 1.9.0. I want mock the behaviour for a single method of a class in a JUnit test, so I have
final MyClass myClassSpy = Mockito.spy(myInstance);
Mockito.when(myClassSpy.method1()).thenReturn(myResults);
The problem is, in the second line, myClassSpy.method1() is actually getting called, resulting in an exception. The only reason I'm using mocks is so that later, whenever myClassSpy.method1() is called, the real method won't be called and the myResults object will be returned.
MyClass is an interface and myInstance is an implementation of that, if that matters.
What do I need to do to correct this spying behaviour?
Let me quote the official documentation:
Important gotcha on spying real objects!
Sometimes it's impossible to use when(Object) for stubbing spies. Example:
List list = new LinkedList();
List spy = spy(list);
// Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)
when(spy.get(0)).thenReturn("foo");
// You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
In your case it goes something like:
doReturn(resultsIWant).when(myClassSpy).method1();
In my case, using Mockito 2.0, I had to change all the any() parameters to nullable() in order to stub the real call.
My case was different from the accepted answer. I was trying to mock a package-private method for an instance that did not live in that package
package common;
public class Animal {
void packageProtected();
}
package instances;
class Dog extends Animal { }
and the test classes
package common;
public abstract class AnimalTest<T extends Animal> {
#Before
setup(){
doNothing().when(getInstance()).packageProtected();
}
abstract T getInstance();
}
package instances;
class DogTest extends AnimalTest<Dog> {
Dog getInstance(){
return spy(new Dog());
}
#Test
public void myTest(){}
}
The compilation is correct, but when it tries to setup the test, it invokes the real method instead.
Declaring the method protected or public fixes the issue, tho it's not a clean solution.
The answer by Tomasz Nurkiewicz appears not to tell the whole story!
NB Mockito version: 1.10.19.
I am very much a Mockito newb, so can't explain the following behaviour: if there's an expert out there who can improve this answer, please feel free.
The method in question here, getContentStringValue, is NOT final and NOT static.
This line does call the original method getContentStringValue:
doReturn( "dummy" ).when( im ).getContentStringValue( anyInt(), isA( ScoreDoc.class ));
This line does not call the original method getContentStringValue:
doReturn( "dummy" ).when( im ).getContentStringValue( anyInt(), any( ScoreDoc.class ));
For reasons which I can't answer, using isA() causes the intended (?) "do not call method" behaviour of doReturn to fail.
Let's look at the method signatures involved here: they are both static methods of Matchers. Both are said by the Javadoc to return null, which is a little difficult to get your head around in itself. Presumably the Class object passed as the parameter is examined but the result either never calculated or discarded. Given that null can stand for any class and that you are hoping for the mocked method not to be called, couldn't the signatures of isA( ... ) and any( ... ) just return null rather than a generic parameter* <T>?
Anyway:
public static <T> T isA(java.lang.Class<T> clazz)
public static <T> T any(java.lang.Class<T> clazz)
The API documentation does not give any clue about this. It also seems to say the need for such "do not call method" behaviour is "very rare". Personally I use this technique all the time: typically I find that mocking involves a few lines which "set the scene" ... followed by calling a method which then "plays out" the scene in the mock context which you have staged... and while you are setting up the scenery and the props the last thing you want is for the actors to enter stage left and start acting their hearts out...
But this is way beyond my pay grade... I invite explanations from any passing Mockito high priests...
* is "generic parameter" the right term?
One more possible scenario which may causing issues with spies is when you're testing spring beans (with spring test framework) or some other framework that is proxing your objects during test.
Example
#Autowired
private MonitoringDocumentsRepository repository
void test(){
repository = Mockito.spy(repository)
Mockito.doReturn(docs1, docs2)
.when(repository).findMonitoringDocuments(Mockito.nullable(MonitoringDocumentSearchRequest.class));
}
In above code both Spring and Mockito will try to proxy your MonitoringDocumentsRepository object, but Spring will be first, which will cause real call of findMonitoringDocuments method. If we debug our code just after putting a spy on repository object it will look like this inside debugger:
repository = MonitoringDocumentsRepository$$EnhancerBySpringCGLIB$$MockitoMock$
#SpyBean to the rescue
If instead #Autowired annotation we use #SpyBean annotation, we will solve above problem, the SpyBean annotation will also inject repository object but it will be firstly proxied by Mockito and will look like this inside debugger
repository = MonitoringDocumentsRepository$$MockitoMock$$EnhancerBySpringCGLIB$
and here is the code:
#SpyBean
private MonitoringDocumentsRepository repository
void test(){
Mockito.doReturn(docs1, docs2)
.when(repository).findMonitoringDocuments(Mockito.nullable(MonitoringDocumentSearchRequest.class));
}
Important gotcha on spying real objects
When stubbing a method using spies , please use doReturn() family of methods.
when(Object) would result in calling the actual method that can throw exceptions.
List spy = spy(new LinkedList());
//Incorrect , spy.get() will throw IndexOutOfBoundsException
when(spy.get(0)).thenReturn("foo");
//You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
I've found yet another reason for spy to call the original method.
Someone had the idea to mock a final class, and found about MockMaker:
As this works differently to our current mechanism and this one has different limitations and as we want to gather experience and user feedback, this feature had to be explicitly activated to be available ; it can be done via the mockito extension mechanism by creating the file src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker containing a single line: mock-maker-inline
Source: https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2#mock-the-unmockable-opt-in-mocking-of-final-classesmethods
After I merged and brought that file to my machine, my tests failed.
I just had to remove the line (or the file), and spy() worked.
One way to make sure a method from a class is not called is to override the method with a dummy.
WebFormCreatorActivity activity = spy(new WebFormCreatorActivity(clientFactory) {//spy(new WebFormCreatorActivity(clientFactory));
#Override
public void select(TreeItem i) {
log.debug("SELECT");
};
});
As mentioned in some of the comments, my method was "static" (though being called on by an instance of the class)
public class A {
static void myMethod() {...}
}
A instance = spy(new A());
verify(instance).myMethod(); // still calls the original method because it's static
Work around was make an instance method or upgrade Mockito to a newer version with some config: https://stackoverflow.com/a/62860455/32453
Bit late to the party but above solutions did not work for me , so sharing my 0.02$
Mokcito version: 1.10.19
MyClass.java
private int handleAction(List<String> argList, String action)
Test.java
MyClass spy = PowerMockito.spy(new MyClass());
Following did NOT work for me (actual method was being called):
1.
doReturn(0).when(spy , "handleAction", ListUtils.EMPTY_LIST, new String());
2.
doReturn(0).when(spy , "handleAction", any(), anyString());
3.
doReturn(0).when(spy , "handleAction", null, null);
Following WORKED:
doReturn(0).when(spy , "handleAction", any(List.class), anyString());

How Dependency Injection Manually Implemented?

How we can manually inject an object without using the facility of containers. I did something similar through reflection as follows.
Class actionClass = Class.forName("SampleClass");
Object actionObject = actionClass.newInstance();
Method reqMethod = actionClass.getMethod("setRequest", HttpServletRequest.class);
reqMethod.invoke(actionObject,request);
is it the right way to do DI?
My intention is to pass request object to different controller classes dynamically from a dispatcher filter,where we get request and response objects.
I am fearing about the performace of reflection.Is there any replacement for doing DI?
Dependency injection is nothing more than providing a class with its dependencies, rather than have it find them itself (via singletons/lookups etc.). So you can do it in code trivially thus:
DatabaseConnection dc = new DatabaseConnection();
MyDAO dao = new MyDAO(dc);
(pseudocode). Here the MyDAO is being injected with a database connection. If that database connection implements an interface you can easily mock this out during testing.
Well, when you set one object into another object using setter method or through a constructor it also is the dependency injection. Dependency injection only means creating relationship(dependency) in objects.
Using reflection as you did is just another form of it.
Why would you use reflection? Why not simply:
SampleClass action = new SampleClass();
action.setRequest(request);
That does the same thing, but is more readable, allows the compiler to check that the types and methods actually exist, provides you with Javadoc for the Method invoked, enables your IDE to assist in refactorings, ...
And it still is dependency injection, because the action doesn't go looking for its request, but receives the request during initialization.
Edit: Thorbjørn requested I show how that action would be used. It would itself be injected (using a setter) into whatever component uses the action. The component would then use the injected action object.
SampleClass action = new SampleClass();
action.setRequest(request);
Servlet servlet = new ActionBasedServlet();
servlet.setAction(action);
If servlet is intended to live longer than action, i.e. it should use a fresh Action each time it needs one, one can instead setter-inject an ActionFactory into servlet.
In this concrete case, I'd question whether the action really needs to keep a request as part of its state, or can be immutable and simply act on the request passed by the Servlet as method parameter. In that case, the boot-time initialization would do:
SampleClass action = new SampleClass();
Servlet servlet = new ActionBasedServlet();
servlet.setAction(action);
and ActionBasedServlet would define
public void serve(Request req, Response resp) {
foo();
action.act(req, resp);
bar();
}
Dependency Injection implies you get properly initialized references appearing "by magic".
You call the setRequest() method with the request object, but DI frequently also allows for setting the fields without invoking methods.
Guice does not as such require a container, but uses class loader magic started in the main method. Would that be useable for you?
Spring framework is one of the most popular DI implementations. It is also opensource.
You can check out the class org.springframeowrk.beans.BeanUtils, specifically the methods copyProperties (all 4 of them) for examples on how to do this.
For more info you can also see the class hierarchy of org.springframework.beans.factory.BeanFactory for different strategies.

Categories

Resources