How to mock querydsl query? - unit-testing

In my prod code I have the following queryDsl query:
Collection<String> myList = new ArrayList<>();
myList.add("blue");
myList.add("green");
myList.add("yellow");
QAnimal qAnimal = QAnimal.animal;
return animalRepository.exists(
qAnimal.color.in(myList).and(
qAnimal.name.eq("animal_name")
)
);
I want to mock this queryDsl query using Mockito. In my test file, in the setup method I did:
Collection<Book> myList = new ArrayList<>();
myList.add("blue");
myList.add("green");
myList.add("yellow");
QAnimal qAnimal = QAnimal.animal;
when(qAnimal.color.in(myList)).thenReturn((Expressions.asBoolean(false)));
when(qAnimal.name.eq("animal_name")).thenReturn((Expressions.asBoolean(true)));
When running the test, I receive the following problem:
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
2. inside when() you don't call method on mock but on some other object.
I can't create a JPAQuery object, only use that kind of queries.

Why would you mock JPAQuery? At this point you're either testing the internals of Querydsl, or making sure that you wrote what you wrote. Just mock the entire AnimalRepository instead. And if you want to test animalRepository properly, its best to do so in an integration test that actually executes the query against a database. There is also the possibility to execute the query against mock data using querydsl-collections.
If you insist on mocking JPAQuery with Mockito stubs however, the easiest way to mock builder API's, like for example JPAQuery, is to use Answers.RETURNS_SELF as default stub.
For example, use the following to instantiate your queryMock:
#Mock(answer = Answers.RETURNS_SELF) JPAQuery queryMock;

Related

Mocking a return value for a companion object method mockito

I'm having an issue with mocking a class with a companion object using mockito. It looks similar to this
#Component
class Util {
companion object {
fun generateName(job: Job) {
return job.name + "_" + (System.currentTimeMillis()/100L).toString()
}
}
}
I am trying to mock this class so I can do something like this:
I mocked the utility in test file like
var util : Util.Companion = mock()
Now inside my test I want to do the following:
#Test
fun "test function"() { //(dont have the symbols, not using the work laptop, excuse the syntax error)
whenever(util.generateName(job)).thenReturn("mystring")
}
Since our job names contain timestamps, I need this to work otherwise my unit tests won't work. Needless to say, this whenever is not working and my functions return the "correct" result when mocked, instead of the one I want provided in the return clause, otherwise during inserts I will always get nulls since I can't mock the timestamps. Please don't suggest different mocking libraries and such, there's already almost 100 tests written with mockito, so that is not an option.
You need to mock creating the companion object, which means compiler creates empty constructor of the class and use that constructor to create the companion object of that class.
You need specifically to return mocked object whenever the constructor is called, i.e new instance for that calls is created.
This doesn't play well with Mockito. I won't suggest you PowerMockito, that's like shooting yourself in the stomach.

How to mock parameterized method in codeception framework

I have one parameterized method which accept string parameter and returns data upon passed param. I am using codeception framework for writing unit testing for php-zend project.
Method: getDataByView($view) $view can be default, all.
So I want mock this method such way it behave & return result based on passed params. I didnt get way in codeception framework so used phpunit code for that. But getting problems in that.
$map = array(
array('default', $default),
array('all', $all)
);
$mock = $this->getMockBuilder('ViewTable')
->setMethods(['getDataByView'])
->disableOriginalConstructor()
->getMock();
$mock->expects($this->any())
->method('getDataByView')
->will($this->returnValueMap($map));
Actually this code work as per my expectation. Since I am using setMethods() it calls the ViewTable class constructor. If I dont use setMethods then It doesn't call constructor.
Problems:
I want to mock only one method of class, so I have used
setMethods() but it calls mock class constructor. I dont want that.
How can it be solved in phpunit.
How to mock parameterized method in codeception framework.

how to mock a service method inside a controller for unit testing in grails using JUnit and when to use mockController

Help me understand how to mock a service method inside a controller for unit testing in grails using JUnit
I was trying to write a unit test case for my controller "add".
void testAdd_UT_03(){
......declaring and assigning prerequisites
controller.add() // This is the controller i want to unit test
.... asserting
}
//Controller
def add{
def a =someService.method()
}
Inside controller, some service methods are getting called which in turn is using HQL statements. Since i could not find a way to deal with HQL statements in unit testing, i want to mock the service method itself. ( i want the service method to return the predefined output).
Could someone please explain how to achieve this?
Could you also explain when to use mockController? what we really achieve by mocking something? ( i dint get the real picture as i am entirely new to this)
Thanks in advance,
BK
you can add the following code in the setUp method of your test to mock the service method and when you call the method "add" method on your controller it will call the mocked service method.
def predifinedOutput
void setUp(){
def mockControl = mockFor(YourService)
//params are the parameters passed to the service method
mockControl.demand.yourServiceMethod(0..10) { params->
predifnedOutput = "predifinedOutput"
return "predefined output"
}
controller.yourService = mockControl.createMock()
}

Mock UserContext and FacesContext - jUnit

I'm trying to write some basic backingBean tests but I'm stuck with mocking the UserContext and facesContext.
This code is in the code that I'm trying to test:
UserContext uc = ContextProvider.getContext();
Locale locale = uc.getLocale();
ResourceBundle bundle = ResourceBundle.getBundle("AppMessages", locale);
String message = bundle.getString("this.is.the.message.key");
In another block of code I've got the following:
FacesContext fc = FacesContext.getCurrentInstance();
fc.getExternalContext().redirect(handleRedirect("someString"));
How could I mock these in a standard jUnit test using only mockito? Or do I have to use something like PowerMock?
Mockito can't mock static methods. You have a few options though:
Extract the code under test to methods which takes the UserContext and ResourceBundle or FacesContext instances as arguments
Wrap the static method calls in a factory object, and pass the factory objact instance as an argument to the code under test
PowerMock is an option, but slows down test execution and in my opinion allows bad-practice solutions
Instead create mocks for yourself, you can use Apache MyFaces Test, which provided already prepared Mock Objects for JSF artifacts. It will work better in a more wide range of cases, with less effort.

Strategies to mock a webservice

I'm implementing a client consuming a webservice. I want to reduce dependencies and decided to mock the webservice.
I use mockito, it has the advantage vs. EasyMock to be able to mock classes, not just interfaces. But that's not the point.
In my test, I've got this code:
// Mock the required objects
Document mDocument = mock(Document.class);
Element mRootElement = mock(Element.class);
Element mGeonameElement = mock(Element.class);
Element mLatElement = mock(Element.class);
Element mLonElement = mock(Element.class);
// record their behavior
when(mDocument.getRootElement()).thenReturn(mRootElement);
when(mRootElement.getChild("geoname")).thenReturn(mGeonameElement);
when(mGeonameElement.getChild("lat")).thenReturn(mLatElement);
when(mGeonameElement.getChild("lon")).thenReturn(mLonElement);
// A_LOCATION_BEAN is a simple pojo for lat & lon, don't care about it!
when(mLatElement.getText()).thenReturn(
Float.toString(A_LOCATION_BEAN.getLat()));
when(mLonElement.getText()).thenReturn(
Float.toString(A_LOCATION_BEAN.getLon()));
// let it work!
GeoLocationFetcher geoLocationFetcher = GeoLocationFetcher
.getInstance();
LocationBean locationBean = geoLocationFetcher
.extractGeoLocationFromXml(mDocument);
// verify their behavior
verify(mDocument).getRootElement();
verify(mRootElement).getChild("geoname");
verify(mGeonameElement).getChild("lat");
verify(mGeonameElement).getChild("lon");
verify(mLatElement).getText();
verify(mLonElement).getText();
assertEquals(A_LOCATION_BEAN, locationBean);
What my code shows is that I "micro-test" the consuming object. It's like I would implement my productive code in my test. An example for the result xml is London on GeoNames.
In my opinion, it's far too granular.
But how can I mock a webservice without giving everystep? Should I let the mock object just return a XML file?
It's not about the code, but the approach.
I'm using JUnit 4.x and Mockito 1.7
I think the real problem here is that you have a singleton that calls and creates the web service so it is difficult to insert a mock one.
You may have to add (possibly package level) access to the singleton class. For example if the constructor looks something like
private GeoLocationFactory(WebService service) {
...
}
you can make the constructor package level and just create one with a mocked web service.
Alternatively you can set the webservice by adding a setter method, although I don't like mutable Singletons. Also in that case you have to remember to unset the webservice afterwards.
If the webservice is created in a method you might have to make the GeoLocationFactory extensible to substitute the mock service.
You may also look into remove the singleton itself. There are articles online and probably here on how to do that.
you really want to be mocking the results returned from the webservice to the code that will be using the result. In your example code above you seem to be mocking mDocument but you really want to pass in an instance of mDocument that has been returned from a mocked instance of your webservice and assert that the locationBean returned from the geoLocationFetcher matches the value of A_LOCATION_BEAN.
The easiest option would be to mock the WebService client,
when(geoLocationFetcher.extractGeoLocationFromXml(anyString()))
.thenReturn("<location/>");
You can modify the code to read the response xml from the file system.
Sample code can be found here: Mocking .NET WebServices with Mockito