Mockito -mocking implementation class - junit

Hi i am trying to mock dao layer
my application has some class hire achy like this Application->parser->dao(interface)->dao implementation class
my problem is when i am mocking dao interface or daoimp class using mockito
in my test case they are not working simply test case going to db how to do make our test case to use these mocked objects
#RunWith(MockitoJUnitRunner.class)
public class CsvDataLoadServiceImplTest {
#Mock private MeteringDataDao meteringDataDao;
List<Object> persistedList;
Object meteringData;
List<Object> s=new ArrayList<Object>();
#SuppressWarnings({ "rawtypes", "unchecked" })
#Before public void setup(){
Mockito.doAnswer(new Answer<List<Object>>() {
#Override
public List<Object> answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
System.out.println("persist all");
if(persistedList == null){
persistedList = (List)args[0];
}
else
persistedList.addAll((List)args[0]);
return null;
}}).when(meteringDataDao).persistAll(anyList());
Mockito.doAnswer(new Answer<Object>() {
#Override
public Object answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
if(meteringData == null)
meteringData = (List)args[0];
return true;
}}).when(meteringDataDao).persist(anyObject());
}
#After public void tearDown(){
persistedList = null;
meteringData = null;
}
#Test
public void testDataAccuricy(){
CsvDataLoadService csvDataLoadService =new CsvDataLoadServiceImpl();
csvDataLoadService.loadRackspaceCsvData();
}
}

CsvDataLoadService csvDataLoadService = new CsvDataLoadServiceImpl();
You're constructing an instance of the service, but this instance doesn't use the DAO you mocked. It uses another one. You need something like
CsvDataLoadService csvDataLoadService =
new CsvDataLoadServiceImpl(meteringDataDao);

Your question is a little badly phrased, so sorry if I appear to have misunderstood you.
#JBNizet answer is correct, you're not using the mocked object, but rather than changing the code for a test you should simply change the test. This is always a best practice when writing your tests.
You haven't assigned the mocked object to the service, so I'm assuming that the MeteringDataDao object is actually instantiated inside the class you're attempting to test?
If so, then you will need something more powerful than Mockito (Unless you want to reproduce the capabilities of a more powerful already existing library). I would suggest PowerMockito, which I have used in the past for something exactly like this.
A good example of using powermockito to mock the constructor of a class can be seen in a few answers on SO already, so I'll just link to them rather than try and re-explain their already clear answers:
Powermock constructor mocking has no effect on the instantiated object
mockito mock a constructor with parameter

Related

Null pointer exception in method that calls another method Mockito

I am new to Mockito and Powermockito. I have a class to test which interacts with the database in order find and also delete data from the database through different public methods. The application is typical Java EE application and the The class under test belongs to Service package in Businesslogic. The method which I want to test looks like below :
public List<QuestionDtoWrapper> searchInQuestions(final Integer ID, final Integer catID,
final String searchString, final String language) {
final List<QuestionDtoWrapper> result = new ArrayList<>();
//In line below I get null pointer exception although I have stubbed this method
final List<QuestionDtoInt> questions = facade.findQuestionsByCatTemplate(ID, catID,
searchString, language);
for (final QuestionDtoInt question : questions) {
result.add(new QuestionDtoWrapper(question));
}
Collections.sort(result, new QuestionComparator(new Locale("de")));
return result;
}
This is how I tried to test the method in my Junit Test:
#RunWith(MockitoJUnitRunner.class)
#PrepareForTest(QuesService.class)
public class QuesServiceTest {
#Mock
QuesFacade mockFbFacade;
#Mock
List<QuesDtoInt> questions;
#Spy
QuesService myService = new QuesService();
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
#Test
public void testSearchInQuestions() throws ParseException {
PowerMockito.doReturn(questions).when(mockFbFacade).findQuestionsByCatTemplate(anyInt(), anyInt(), anyString(), anyString());
List<QuestionDtoWrapper> res = null ;
res = myService.searchInQuestions(anyInt(), anyInt(), anyString(), anyString());
assertNotNull(res);
}
I am getting Null pointer exception in Line where the method calls another method. See my comment in source code. Could someone please let me know:
1) Am I using mockito for the correct subject ? Should I use real Test data ? But what about the database connections n all ? I tried that approach and ended up using Mockito only.
2) Why am I getting Null pointer exception although I have stubbed that method with Powermockito ?
3) please provide your valuable suggestions to test the given method correctly.
Note:- I am not allowed to do any refactoring in the code.

Mockito is calling real method and thenReturn does not work

I have read some post about it but nothing solved my problem. I have a class which is singleton and one method of this class is being called inside another class. I need to mock this method call.
Class SingletonClass
{
public static SingletonClass instance()
{
......
return instance;
}
public boolean methodToBeMocked(Object obj)
{
return false;
}
}
And the another class is :
Class A
{
Object doSomeStuff()
{
......
boolean result = SingletonClass.instance.methodToBeMocked();
}
}
And I am mocking the method methodToBeMocked in my test class. I have tried to use doReturn instead of thenReturn as it is suggested in other posts but it did not help.
My test class is :
Class TestClass{
Class A a = new A();
public void test()
{
SingletonClass singletonClass = mock(SingletonClass.class);
doReturn(true).when(singletonClass).methodToBeMocked(any());
a.doSomeStuff(); // here mocked method returns false
// but if I do this below it returns true !!!!
Object obj = new Object();
boolean result = singletonClass.mockedMethod(obj);
}
}
So why I am not getting true when a.doSomeStuff is called ? What is wrong here ?
For the benefit of others, I was using the following mock with the expectation it would not call someMock.someMethod(), unlike the when(someMock.someMethod()).doReturn("someString") usage.
Mockito.doReturn("someString").when(someMock).someMethod();
I could not understand why the real someMethod() was still being called. It turns out the method was specified as final. Mockito can't mock static or final methods.
The problem is the static method public static SingletonClass instance(). The standard mockito library does not support mocking of static methods. I seen two solutions.
You can rewrite small your code as:
Add new method getSingletonClassInstance() to be mocked in test
Class A {
Object doSomeStuff()
{
......
boolean result = getSingletonClassInstance();
}
SingletonClass getSingletonClassInstance(){
return SingletonClass.instance.methodToBeMocked();
}
}
use spy from mockito library to create an instance of Class A
import static org.mockito.Mockito.spy;
.....
Class TestClass{
public void test()
{
Class A a = spy(new A());
SingletonClass singletonClass = mock(SingletonClass.class);
doReturn(true).when(singletonClass).methodToBeMocked(any());
doReturn(singletonClass).when(a).getSingletonClassInstance();
a.doSomeStuff(); // here mocked method returns false
// but if I do this below it returns true !!!!
Object obj = new Object();
boolean result = singletonClass.mockedMethod(obj);
}
}
More information about the spy in mockito. Spy used real instance and invoke real method but provide a functionality to mock specific method. Don't worry about the others method they will continue to work with real implementation, only mocked method will be affected.
You can use power mockito to mock the public static SingletonClass
instance()

Mock objects which are initialized in the method itself

Is there any way to mock objects which are initialized in the method itself. For example
void myMethod(){
SampleClass sample = new SampleClass();
int count = sample.getProductCount(5L);
}
I want to mock getProductCount method something like
when(sample.getProductCount(any(Long.class)).thenReturn(10)
But I don't find a way to do so. Any advice?
I'm using #Spy which lets you mock specific method,
A field annotated with #Spy can be initialized explicitly at declaration point.
In your case prepare the spy:
#Spy
private SampleClass sample = new SampleClass();
#BeforeMethod
public void initMocks() {
MockitoAnnotations.initMocks(this);
}
And in test:
doReturn(10).when(sample).getProductCount(any(Long.class));

Can any one help me in mocking a static method which returns an object, and this static method is present in a final class

I need help for below thing,
I have to write a Junit using PowerMock/Mockito for a method which makes a call to a static method of a final class present in an external jar.
The method for which i need to write the JUnit test is:
public class SomeClass {
private PrivateKey privateKeyFromPkcs8(String privateKeyPem) throws IOException {
Reader reader = new StringReader(privateKeyPem);
Section section = PemReader.readFirstSectionAndClose(reader, "PRIVATE KEY");
if (section == null) {
throw new IOException("Invalid PKCS8 data.");
}
byte[] bytes = section.getBase64DecodedBytes();
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
try {
KeyFactory keyFactory = SecurityUtils.getRsaKeyFactory();
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
} catch (NoSuchAlgorithmException exception) {
} catch (InvalidKeySpecException exception) {
}
throw new IOException("Unexpected exception reading PKCS data");
}
}
In the above code PemReader is a final class and readFirstSectionAndClose(reader, "PRIVATE KEY") is a static method in PemReader.
I have tried writing the test shown below but Section object(section) is showing as null while debugging. Perhaps the actual code (PemReader.readFirstSectionAndClose(reader, "PRIVATE KEY")) is getting called instead of the mock.
#RunWith(PowerMockRunner.class)
#PrepareForTest({SomeClass.class,PemReader.class})
public class SomeClassTest {
#InjectMocks
SomeClass mockSomeClass;
#Mock
private Reader mockReader;
#Mock
private Section mockSection;
#Test
public void testPrivateKeyFromPkcs8() throws Exception {
PowerMockito.mockStatic(PemReader.class);
Mockito.when(PemReader.readFirstSectionAndClose(mockReader, "PRIVATE KEY")).thenReturn(mockSection);
assertNotNull(mockSomeClass.privateKeyFromPkcs8(dummyPrivateKey));
}
}
Please help me in writing a Junit using powermockito/mockito
You have to prepare the final, static class.
Here's an example using the PowerMock annotations for JUnit:
#RunWith(PowerMockRunner.class)
#PrepareForTest({PemReader.class})
public class PemReaderTest {
#Mock
private Reader mockReader;
#Mock
private Section mockSection;
#Test
public void testMockingStatic() {
PowerMockito.mockStatic(PemReader.class);
Mockito.when(PemReader.readFirstSectionAndClose(mockReader, "PRIVATE KEY")).thenReturn(mockSection);
Assert.assertEquals(mockSection, PemReader.readFirstSectionAndClose(mockReader, "PRIVATE KEY"));
}
}
For completeness, here's the definition of PemReader:
public final class PemReader {
public static Section readFirstSectionAndClose(Reader reader, String key) {
return null;
}
}
The above test passes with the following versions:
JUnit: 4.12
Mockito: 2.7.19
PowerMock: 1.7.0
Update 1: based on your updated question. Your test case will pass (or at least the invocation on PemReader.readFirstSectionAndClose will return something) if you just make this change:
Mockito.when(PemReader.readFirstSectionAndClose(
Mockito.any(Reader.class),
Mockito.eq("PRIVATE KEY"))
).thenReturn(mockSection);
The version of this instruction in your current test case relies on equality matching between the StringReader which your code passes into readFirstSectionAndClose and the mocked Reader which your test case supplies. These are not 'equal' hence the mocked invocation's expectations are not met and your mockSection is not returned.
A few, unrelated, notes:
There is no need to include SomeClass.class in #PrepareForTest, you only need to include the classes which you want to mock in that annotation, since SomeClass is the class you are trying to test there is no mocking required for that class.
Using #InjectMocks to instance SomeClass is a bit odd, since SomeClass has no (mockito provided) mocks to inject into it :) you can replace this declaration with SomeClass someClass = new SomeClass();
In the code you supplied SomeClass.privateKeyFromPkcs8 has private scope so it cannot be tested (or called in any way) from SomeClassTest.

mock a method call with dynamic parameter

I have a method as follows
private void validate(String schemaName){
....
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);**strong text**
Source schemaFile = new SteamSource(getClass().getClassLoader().getResourceAsStream(schemaName));
Schema schema = factory.newSchema(schemaFile);
....
}
This method get called from another method which I need to test(Using easymock and powermock). I'm struggling to mock following line
Source schemaFile = new SteamSource(getClass().getClassLoader().getResourceAsStream(schemaName));
Can someone give me a clue on this?
Current Status
Following is the mock statement
expectNew(StreamSource.class, anyObject(InputStream.class)).andReturn(mockedobject);
Powermock.replay(mockedobject, StreamSrouce.class);
This throws the following exception.
org.powermock.reflect.exceptions.TooManyConstructorsFoundException: Several matching constructors found, please specify the argument parameter types so that PowerMock can determine which method you're referring to.
Matching constructors in class javax.xml.transform.stream.StreamSource were:
I think you can do it using powermock in the following way (I'm just following the tutorial here):
Let's say you're class looks like this:
public class MyClass {
private void validate(String schemaName) {
....
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);**strong text**
Source schemaFile = new SteamSource(getClass().getClassLoader().getResourceAsStream(schemaName));
Schema schema = factory.newSchema(schemaFile);
....
}
}
You should create a test class like this:
#RunWith(PowerMockRunner.class)
#PrepareForTest(MyClass.class)
public class MyClassTest {
private MyClass testedClass = new MyClass();
private ClassLoader mockedClassLoader = createMock(ClassLoader.class);
private InputStream mockedInputStream = createMock(InputStream.class);
#Before
public void setUp() {
PowerMock.createPartialMock(MyClass.class, "getClass");
expect(testedClass.getClass()).andReturn(mockedClassLoader);
expected(mockedClassLoader.getResourceAsStream(***You string***)).andReturn(mockedInputStream);
replayAll(); // Not sure if that's the name of the method - you need to call replay on all mocks
}
#Test
public void testValidate() {
// Run your test logic here
}
}
Please excuse me if some of the easymock methods I used are named a bit differently. But this is the basic idea.
I think you need one or a combination of the following. Use Powermock constructor mocking for the new StreamSource as documented here: Powermock MockConstructor. You will probably also need to use a mock for SchemaFactory which mean you will need to mock the static factory method call via Powermock: MockStatic