Mock a statement by using MockIto - junit

I want to write a test method for a service method. In this service method we are calling a query that fetch the data from database and that value is used in the function to do some processing. I want to stub only this db call. here is my function
public arraylist retrieveSomthing(JdbcTemplate){
//some processing is happening
List<Map<String,Object>> result = JdbcTemplate.queryForList("QueryName");
//some processing is happening for the result return from the query.
}
I want to write the test for the above function but I want to stub only the Jdbc.queryforList statement.
Please help me How to go stub the statement.
Thanks in Advance.

#Test
public void testRetrieveSomthing() {
JdbcTemplate jdbcTemplate = mock(JdbcTemplate.class);
List < .. > results = ///something you would do dummy return
when(jdbcTemplate.queryForList(anyString())).thenReturn(results);
List < .. > alist = instance.retrieveSomthing(jdbcTemplate);
assertEquals(alist, expectedList);
}

It's easy to do
1) Mock the jdbctemplate object like below:
#Mock private JdbcTemplate jdbcTemplate;
2) Since jdbcTemplate.queryForList("QueryName") returns list, make sure that you have created a List object and returning that value while stubbing (like below)
List<Example> result = new ArrayList();
result.add("dummy values");
result.add("dummy values");
then
//import static org.mockito.Matchers.anyString;
Mockito.when(jdbcTemplate.queryForList(anyString()).thenReturn(result);
PS: Points to remember while mocking and stubbing are,
1) while dealing with List objects create new object and return as on-stubbing value of actual test class
2) Use matchers like anyString() instead of using some text.
Hope it is useful.

Related

How to know current #Test method in #before method in Junit 4

I have following code in JUnit test class.
How to know in #Before method, which #Test method is to be executed now.
Since #Before method is getting called prior to both #Test method.
I want to write code in #Before such that it will setup relevant test data for corresponding #Test Method.
/*
* #Before is called before executing each test method.
* We are using it to setup test data before executing test case
* */
#Before
public void prepareForTest()throws Exception{
System.out.println("prepareForTest called");
}
/**
* This method to check sub requirements are present
* 1. AssertNotNull variant
* 2. Condition that MapList is not empty
*/
#Test
public void testGetSubRequirementNotNull()throws MatrixException{
System.out.println("testGetSubRequirementNotNull called");
String strReqObjectId = propertySet.getProperty("Requirement.testGetSubRequirementNotNull.objectId");
RequirementService reqService = serviceFactory.getRequirementService(context);
MapList mlSubReqList = reqService.getSubRequirement(context, strReqObjectId);
assertNotNull("SubRequirement List is null", mlSubReqList);
assertFalse("SubRequirement list is empty", mlSubReqList.isEmpty());
}
/**
* This method is to check sub requirements are not present
* 1. AssertNull variant
* 2. Condition that MapList is empty
*/
#Test
public void testGetSubRequirementNull()throws MatrixException{
System.out.println("testGetSubRequirementNull called");
String strReqObjectId = propertySet.getProperty("Requirement.testGetSubRequirementNotNull.objectId");
RequirementService reqService = serviceFactory.getRequirementService(context);
MapList mlSubReqList = reqService.getSubRequirement(context, strReqObjectId);
assertNull("SubRequirement List is not null", mlSubReqList);
assertTrue("SubRequirement list is not empty", mlSubReqList.isEmpty());
}
The documentation of #Before says:
When writing tests, it is common to find that several tests need similar objects created before they can run.
In my experience you should only create Objects in your #Before Methode that are used by all of the testmethods in your class.
If one of your tests does need an object that is only used there the test should instantiate this object by itself.
If a few (not all) of your tests needs the same (or similar) object I would recommend to extract the instantiation of the object in a private helper method of the class that is called by each testmethod. This would also adhere to the DRY principle.
tl;dr;
I don't think you need to know which test will be executed next. Each Test should instantiate the objects it needs itself.
In case we need to know which #Test method currently will execute in #Before method,
this can be achieved technically like below using #Rule TestName field.
#Rule public TestName testName = new TestName();
/*
* #Before is called before executing each test method.
* This method is called before executing testGetSubRequirement method.
* We are using it to setup test data before executing test case
* */
#Before
public void prepareForTest()throws Exception{
System.out.println("prepareForTest called::"+testName.getMethodName());//it will print name of #Test method to be excuted next
}

JUnit Mockito returning LinkedList instead of ArrayList

I have been tasked to figure out why this JUnit Test is failing. What I have found is that instead of returning an ArrayList (like the getDeligationsForLoggedInUser is SUPPOSED to return, it returns a LinkedList for "userList".
#SuppressWarnings("unchecked")
#Test
public void test_getDelegationsForLoggedInUser()
{
String userId="Abcd";
List<String> expectedUserList= new ArrayList<String>();
expectedUserList.add("efghi");
expectedUserList.add("jklmn");
expectedUserList.add("opqrs");
when(namedParameterJdbcTemplate.queryForObject(anyString(),anyMap(), any(RowMapper.class))).thenReturn(expectedUserList);
List<String> userList= workflowProcessDAOImpl.getDelegationsForLoggedInUser(userId);
verify(namedParameterJdbcTemplate, times(1)).query(sqlCaptor.capture(), namedParameterMap.capture(), rowMapperCaptor.capture());
assertThat(userList, is(expectedUserList));
assertThat(sqlCaptor.getValue(), is(SQLConstantsSysConfigV1.getInstance().GET_USERIDS_FOR_DELEGATES));
}
Does anyone have any idea why this is the case?
You mock in this test the method queryForObject, but test on the method query.
I suppose that your code defines a mock of the function somwhere else, isn't it? It could then simply be the result of a copy/paste operation...
I also had the same problem. To solve that I replaced Mockito.anyList() (if param required is list) and Mockito.anyLong() (if param required is long). Example:-
Mockito.when(testService.getData(Mockito.anyLong(),
Mockito.anyList(), Mockito.anyList())).thenReturn(SOME_RESPONSE_DATA);

Can we mock a method with powermockito and testng

I am writing a TestNG testcase which extends atgdustcase. I need to mock a method in class B. This class B is injected into class A using properties file in ATG. Class C is a test class for testing functionality of class A. D is a test class which extends AtgDustCase.
#RunWith(PowerMockRunner.class)
#PrepareForTest({A.class, B.class})
Public class c extends D{
#InjectGlobalComponent(Path for component A)
#InjectMocks
private A aClass;
public void testMethod(){
String string = "abc";
Map map = new HashMap();
map.put("a", "c");
aClass = getRequest.resolveName(Component A path);
B b = PowerMockito.mock(B.class);
A a = PowerMockito.spy(new A());
PowerMockito.whenNew(A.class).withNoArguments().thenReturn(a);
a.setB(B);
PowerMockito.when(a.getB()).thenReturn(b);
Mockito.stub(b.getMethodToMock(string)).toReturn(map);
Mockito.verify(b).getMethodToMock(string);
aClass.invokeTestMethod();// This method calls the b.getMethodToMock()
}
}
I need to mock getMethodToMock(). When I execute invokeTestMethod(), this calls getMethodToMock(). At that time, map should be returned. Instead it is executing getMethodToMock() and it is throwing an error(The problem with execution is I need to fetch some records from DB. I need to mock this method and return a map which contains information retrieved from DB). I am not sure whether mocking is happening properly or not, as in debug mode I am able to see that the getMethodToMock() is getting invoked. Please help me how can I mock this method and skip the execution of this method.
Note: I tried using Powermockito, but my testcase is TestNGsuite. I need to run TestNGSuite instead of running it as Junit.

Unable to mock URL class using PowerMockito/Mockito

I am trying to use PowerMockito to mock the creation of the java.net.URL class in my code that I'm testing. Basically, I want to prevent the real HTTP request from occurring and instead 1) check the data when the request is made and 2) supply my own test data back on a mocked response. This is what I'm trying:
#RunWith(PowerMockRunner.class)
#PrepareForTest({ URL.class, MockedHttpConnection.class })
public class Test {
URL mockedURL = PowerMockito.mock(URL.class);
MockedHttpConnection mockedConnection = PowerMockito.mock(MockedHttpConnection.class);
...
PowerMockito.whenNew(URL.class).withParameterTypes(String.class).withArguments("MyURLString").thenReturn(mockedURL);
PowerMockito.when(mockedURL.openConnection()).thenReturn(mockedConnection);
...
}
The code that I want to test looks like this:
URL wlInvokeUrl = new URL(wlInvokeUrlString);
connection = (HttpURLConnection) wlInvokeUrl.openConnection();
Earlier in my test scenario I mock the wlInvokeUrlString to match "MyURLString". I've also tried using various other forms of the whenNew line, trying to inject the mock. No matter what I try, it never intercepts the constructor. All I want to do is "catch" the call to openConnection() and have it return my mocked HTTP connection instead of the real one.
I have mocked other classes ahead of this one in the same script and these are working as expected. Either I need a second pair of eyes (probably true) or there is something unique about the URL class. I did notice that if I use "whenNew(URL.class).withAnyArguments()" and change the "thenReturn" to "thenAnswer" I could get it to trigger. Only problem is I never get the URL call for my code. What I see is an invocation of the 3-argument constructor for URL.class with all nulls for the parameters. Could it be this class is from the Java runtime and is bootstrapped by the test runner? Any help is much appreciated.
It's a common mistake when use PowerMockito.whenNew.
Note that you must prepare the class creating the new instance of MyClass for test, not the MyClass itself. E.g. if the class doing new MyClass() is called X then you'd have to do #PrepareForTest(X.class) in order for whenNew to work
From Powermock wiki
So, you need a bit change your test and add to #PrepareForTesta class which create a new instance of URLlike:
#RunWith(PowerMockRunner.class)
#PrepareForTest({ URL.class, MockedHttpConnection.class , ConnectionUser.class})
public class URLTest {
public class URLTest {
private ConnectionUser connectionUser;
#Before
public void setUp() throws Exception {
connectionUser = new ConnectionUser();
}
#Test
public void testName() throws Exception {
URL mockedURL = PowerMockito.mock(URL.class);
MockedHttpConnection mockedConnection = PowerMockito.mock(MockedHttpConnection.class);
PowerMockito.whenNew(URL.class).withParameterTypes(String.class).withArguments("MyURLString").thenReturn(mockedURL);
PowerMockito.when(mockedURL.openConnection()).thenReturn(mockedConnection);
connectionUser.open();
assertEquals(mockedConnection, connectionUser.getConnection());
}
}
where:
public class ConnectionUser {
private String wlInvokeUrlString = "MyURLString";
private HttpURLConnection connection;
public void open() throws IOException {
URL wlInvokeUrl = new URL(wlInvokeUrlString);
connection = (HttpURLConnection) wlInvokeUrl.openConnection();
}
public HttpURLConnection getConnection() {
return connection;
}
}
I'm not sure the difference between .withParameterTypes(x) and .withArguments(x) but I believe you need to set it up as follows for your code to work. Give it a try and let me know if this doesn't help.
PowerMockito.when(mockedURL.openConnection()).thenReturn(mockedConnection);
PowerMockito.whenNew(URL.class).withArguments(Mockito.anyString()).thenReturn(mockedURL);
The problem is that the arguments of the real call are not matching with the expected in your mock.
PowerMockito.whenNew(URL.class).withParameterTypes(String.class).withArguments("MyURLString").thenReturn(mockedURL) will return mockedURL only the call is new URL("MyURLString").
If you change it to:
PowerMockito.whenNew( URL.class ).withParameterTypes( String.class )
.withArguments( org.mockito.Matchers.any( String.class ) ).thenReturn( mockedURL );
It will catch any string passed to the constructor URL(String) (even null) and return your mock.
When you tried
"whenNew(URL.class).withAnyArguments()" and change the "thenReturn" to
"thenAnswer" I could get it to trigger. Only problem is I never get
the URL call for my code. What I see is an invocation of the
3-argument constructor for URL.class with all nulls for the
parameters.
PowerMock will try to mock all constructors (org.powermock.api.mockito.internal.expectation.DelegatingToConstructorsOngoingStubbing.InvokeStubMethod at line 122) then it calls the first one (with 3 arguments) and mock its answer. But the subsequent calls will return the already mocked one because you told it to mock for any arguments. That's why you see just one call with null, null, null in your Answer.

JUnit 4 API Get Handle to a #Test Method

Using JUnit 4 API, is there a way to get a handle to a method in a test class that are annotated with #Test?
Here's what I am currently doing:
JUnitCore core = new JUnitCore();
Request request = Request.aClass(MyTest.class);
Result result = core.run(request);
if(result.wasSuccessful())
System.out.println("SUCCESS"); // or do something else
This code will run all tests in MyTest. However, what I want is to just specify the test class name at the beginning (MyTest.class) and do following in a loop:
Get next #Test annotated test in the class.
Print details
Run the test (possibly using Request.method(MyTest.class, "myTestMethod")
I can perhaps use reflection to get the method names and check if they are annotated with Test, but wanted to see if the JUnit API already provides this functionality.
You can use TestClass:
public void runTests(Class<?> clazz) {
TestClass testClass = new TestClass(MyTest.class);
List<FrameworkMethod> tests = testClass.getAnnotatedMethods(
Test.class);
for (FrameworkMethod m : tests) {
String methodName = m.getName();
Request request = Request.method(clazz, methodName);
JUnitCore core = new JUnitCore();
Result result = core.run(request);
if (result.wasSuccessful())
System.out.println(m + ": SUCCESS");
}
}
}
Note that this is an inefficient way to run tests, especially if you have class rules or you use #BeforeClass or #AfterClass