InvocationTargetException in Mockito - java

I'm getting InvocationTarget Exception in my test case. This is the class which I'm trying to test :
public class UpdateHandler implements Handler {
public void process(UE m, UEC u) {
try {
Info info = facade1.queryInfo(string).getInfo();
Index index = facade2.findindex(string2);
if(facade3.isWhitelisted() {
facade2.update(info, index);
}
} catch(UpdateException e) {
//log
}
}
This is my test file
public class TestFile {
#Mock
protected Facade1 facade1;
#Mock
protected Facade2 facade2;
#Mock
protected Facade3 facade3;
private Info info;
private Index index;
#InjectMocks
private UpdateHandler updatehandler;
#BeforeMethod
public void beforeTest() {
MockitoAnnotations.initMocks(this);
}
#Test
public void Test1() {
info = getInfo();
index = getIndex();
updateHandler.process(UEprepare(), null);
Mockito.when(facade1.queryInfo(Mockito.anyString()).getInfo()).thenReturn(getInfo());
Mockito.when(facade2.findindex(Mockito.anyString()).thenReturn(getIndex());
Mockito.when(facade3.isWhitelisted()).thenReturn(true);
Mockito.verify(facade1, Mockito.times(1).update(info, index);
}
}
getInfo() and getIndex() are two methods I created in the test file just to create a sample object of Info and Index. UEprepare is a method to prepare a sample object of UE. UM can be null. I've checked that's not the issue.
The error I'm getting is Null pointer exception. Specifically, the value of facade1.queryInfo(string) is null. It's supposed to be an object of type InfoResult from which I can extract an object of Info. I checked the queryInfo method and that does not throw a NPE anywhere. It only throws exception of type UpdateException which I've already handled in my code in try catch.
When I dug deeper, I found an InvocationTargetException. I can't specifically understand where that exception is coming from but I think it's got something to do with the queryInfo method.
I've initialized mocks for all the facades I'm using and I think I've used InjectMocks correctly as well so I'm stuck on how to debug this.

There are 2 errors in your code:
Order of methods
You have:
call of method under test
setting expectations Mockito.when
verification of expectations Mockito.verify
while it should be
setting expectations Mockito.when
call of method under test
verification of expectations Mockito.verify
Chained expectations
Mockito.when(facade1.queryInfo(Mockito.anyString()).getInfo()).thenReturn(getInfo());
You need additional mock for result of queryInfo call, let's say #Mock QueryInfo queryInfo. Then, you need 2 calls for setting this expectation:
Mockito.when(facade1.queryInfo(Mockito.anyString()).thenReturn(queryInfo);
Mockito.when(queryInfo.getInfo()).thenReturn(getInfo());

Related

Why does this test pass?

I need your help to understand a unit (method) behaviors within a unit test class shown below.
public void updateAccount(Account account) {
if (!accountExists(account.getAccountNo())) {
throw new AccountNotFoundException();
}
accounts.put(account.getAccountNo(), account);
}
The method shown above tells me that the exception will be thrown if the account is not found
However the 2nd test ( updateNotExistedAccount) method shown below shows that it's expected that the method above (updateAccount ) should throw an exception to past the test. However, newAccount is already initialized /created within the createNewAccount so it exists already. So I assume that the updateNotExistedAccount will failed the test (because updateAccount won't throw exceptions in that case ), however updateNotExistedAccount passed.
public class InMemoryAccountDaoTests {
private static final String NEW_ACCOUNT_NO = "998";
private Account newAccount;
private InMemoryAccountDao accountDao;
#Before
public void init() {
newAccount = new Account(NEW_ACCOUNT_NO, 200);
accountDao = new InMemoryAccountDao();
}
#Test
public void createNewAccount() {
accountDao.createAccount(newAccount);
assertEquals(accountDao.findAccount(NEW_ACCOUNT_NO), newAccount); }
#Test(expected = AccountNotFoundException.class)
public void updateNotExistedAccount() { accountDao.updateAccount(newAccount);
}
Is it wrong if I assume updateNotExistedAccount will fail the test?
Seems like the data are persisted from one test to another.
Try to clean the data after each test.
#After
public void clean(){
// this method will be run after each single #Test method
// you can use this to clean all resoruces after a test. in your case for example
accountDao.deleteById(newAccount.getId());
}
For your test to be complete, and to test the update, I would do something like this:
#Test
public void updateExistingAccount() {
accountDao.createAccount(newAccount);
dbAccount = accountDao.findAccount(newAccount.getId);
dbAccount.setName("");
dbAccount.setSurname("");
// etc...
accountDao.updateAccount(dbAccount);
dbAccountUpdated = accountDao.findAccount(newAccount.getId);
assertEquals(accountDao.findAccount(dbAccountUpdated.getId()), dbAccount);
}
UPDATE
Consider also that #Before and #After runs respectively before and after each single test.
#BeforeClass and #AfterClass respectively before and after all tests.
With the use of these 4 methods you can start always the test with the desired dataset, and after the test clean everything as it were.
Please see:
Difference between #Before, #BeforeClass, #BeforeEach and #BeforeAll
To properly check need to look at your newAccount code as well as what all you are Mocking.
Check your #Before method as that will run before every #Test
Check if which test is running first when you run your suite

PowerMock UnfinishedStubbingException error on final class

Trying to get Mockito and PowerMock to behave, but I'm getting an UnfinishedStubbingException when trying to run this code:
#RunWith(PowerMockRunner.class)
#PrepareForTest(FileIOHelper.class)
public class FileIOHelperTest {
#Test
public void testIOExceptionOnWrite() {
PowerMockito.mockStatic(FileIOHelper.class);
PowerMockito.doThrow(new IOException()).when(FileIOHelper.class);
PowerMockito.verifyStatic();
FileIOHelper.write(Mockito.anyString(), Mockito.anyString());
}
#After
public void validate() {
Mockito.validateMockitoUsage();
}
}
and this IO class
public final class FileIOHelper {
public static void write(final String file, String message, final boolean appendNewLine) {
if(checkArgs(file, message)) {
final Path path = Paths.get(file);
StandardOpenOption mode = StandardOpenOption.APPEND;
if(Files.notExists(path)) {
mode = StandardOpenOption.CREATE_NEW;
}
if(appendNewLine) {
message += System.getProperty("line.separator");
}
try {
Files.write(path, message.getBytes(), mode);
} catch(IOException e) {
handleException(e, "Problem writing to " + file);
}
}
}
private static boolean checkArgs(final String... args) {
if(args != null && args.length > 0) {
for(final String arg : args) {
if(arg == null || arg.isEmpty()) {
return false;
}
}
}
return true;
}
private static void handleException(final IOException e, final String errorMsg) {
handleException(e, errorMsg, true);
}
private static void handleException(final IOException e, final String errorMsg, final boolean printStace) {
checkArgs(errorMsg);
System.err.println(errorMsg);
System.err.println(e.getMessage());
if(printStace) {
e.printStackTrace();
}
}
}
What I want to do is somehow trigger the IOException so handleException can be tested. Why one might ask? I'm looking at my Jacoco report and I see this:
I've looked at:
How to mock a void static method to throw exception with Powermock?
Powermock/mockito does not throw exception when told to
PowerMockito mock static method which throws exception
https://github.com/jayway/powermock/wiki/MockitoUsage#how-to-stub-void-static-method-to-throw-exception
http://www.johnmullins.co/blog/2015/02/15/beginners-guide-to-using-mockito-and-powermockito-to-unit-test-java/
and I'm still completely lost. I have no idea if I need to trigger the IOException or if I can somehow verify the output of handleException without doThrow. Someone, help!
Error log:
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at FileIOHelperTest.testIOExceptionOnWrite(FileIOHelperTest.java:8) // doThrow line
E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, you naughty developer!
3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed
My recommendation: forget about using PowerMock.
If you have to mock static methods, then build your own little wrapper class around that. Then, for testing, your wrapper can return something you control; and for production usage; your wrapper just calls the static method.
PowerMock looks like the solution to many problems; but rather sooner than later, it will be the cause of much more problems. It breaks coverage, it makes it harder to change the underlying JVM, and so on.
Seriously: if your design can only be tested with PowerMock, this is very often a clear indication that your design is bad. So: focus on reworking your code under test; instead of investing time into a tool like PowerMock that does more harm than good.
I have spent countless hours trying to resolve PowerMock problems; and since I started to instead write "better to test" production code ... I have written hundreds or thousands of tests without ever needing PowerMock again.
In your case: start by avoiding static all over the place. Basically you achieve that by (worst case) pulling little wrapper classes around the static calls you have to make. For testing, you can mock the wrapper object; and in production code, you use dependency injection to provide a (singleton/enum) wrapper object that simply makes the static call.
First of all, IOException is checked exception - it should be declared with throws in the method signature. But your method FileIOHelper.write does not have such. This may be the reason of the UnsutisfiedStubbingException.
I do not understand, what your are trying to test: if the FileIOHelper is a mock - handleException will be never called, since it is called by the real write method, not by mocked.
First, you have to mock the class 'Files', not 'FileIOHelper'. FileIOHelper is the tested class. Second, you didn't specified which method should throw IOException. The unit test method should be as follows (supposing the tested method catches and manage the IOException):
#RunWith(PowerMockRunner.class)
#PrepareForTest(Files.class)
public class FileIOHelperTest {
#Test
public void testIOExceptionOnWrite() {
PowerMockito.mockStatic(Files.class);
PowerMockito.doThrow(new IOException()).when(Files.class);
Files.write("path", "message", true);
FileIOHelper.write("path", "message", true);
PowerMockito.verifyStatic();
Files.write("path", "message", true);
}
}

Expecting custom exception instead of null pointer exception while junit testing

I have method in java class :
#Context
UriInfo uriInfo;
public void processRequest(#QueryParam ("userId") #DefaultValue("") String userId)
{
String baseURI = uriInfo.getBaseUri().toString();
if(userId == null)
{
//UserIdNotFoundException is my custom exception which extends Exceptition
throw new UserIdNotFoundException();
}
}
When I'm junit testing the above method expecting for UserIdNotFoundException when userId parameter is Null, I get the following Assertion error : expected an instance of UserIdNotFoundException but <java.lang.NullPointerException> is java.lang.NullPointerException.
#Test
public void testProcessRequest_throws_UserIdNotFoundException()
{
expectedException.expect(UserIdNotFoundException.class);
processRequest(null);
}
My custom exception class :
public class UserIdNotFoundException extends Exception
{
public UserIdNotFoundException()
{
}
public UserIdNotFoundException(String message)
{
super(message);
}
}
I prefer the annotation:
#Test(expected = UserIdNotFoundException.class)
public void testProcessRequest_throws_UserIdNotFoundException() {
processRequest(null);
}
The problem might be that your processRequest implementation might be hitting the NPE before you have a chance to check for user id.
This is a good thing: Your test shows that the implementation does not meet your requirement. You can fix it forever now.
This is what TDD is good for.
You have to write custom Exception class this example might help you.
sample code:
class UserIdNotFoundException extends Exception{
UserIdNotFoundException (String s){
super(s);
}
}
Test Exception:
public void processRequest(String userId)
{
if(userId == null)
{
//UserIdNotFoundException is my custom exception which extends Exception
throw new UserIdNotFoundException("SOME MESSAGE");
}
}
remove default constructor from your exception class, JVM implicitly create it for you/
You probably did not set uriInfo with a value and you're calling a method on a null value. Are you sure you're test is setup to give a value to uriInfo ? Or getBaseUri() might be returning null and calling toString() on it might throw the NullPointerException. This would be done by inspecting the return value of getBaseUri() in a debugger.
Normally you can either run your test with a config with beans for your test or you can add setter to set the value in your class of test to mock it or give a value in test. This should help avoid NullPointerException.
Either way you should always do the fail verification before doing any real work in a method.

How do you expect and verify a private void method call using PowerMockito and TestNG?

I need to write unit tests against a pre-existing code base using TestNG, Mockito and now PowerMockito, to test private and static methods more easily. I am currently trying to write a test against a private void method in a class that we are testing, but am unable to figure it out. In the normal PowerMock API there are methods called replayAll(), verifyAll(), and expectLastCalled(), which are suitable for most purposes. I just can't find good docs that explain how to do it the PowerMockito way. Any explanations or insights on this would be much appreciated.
Method to test:
private void pVMethod(Type param) throws Exception {
param.setA(StaticClass.methodA().toString());
param.setB(StaticClass.methodB().toString());
// getMemo(String label) is in a public class in same package
param.setC(getMemo("memo.provider"));
param.setD(getMemo("memo.item"));
try {
param.setTimestamp(DataTypeFactory.newInstance().newXMLGregorianCalendar(newjava.util.GregorianCalendar()));
} catch (SomeException e) {
...
throw new Exception();
}
}
test attempt:
#Test(expectedExceptions = Exception.class)
public void pVMethod() throws Exception {
TestClass testMock = mock(TestClass.class);
Exception exception = mock(Exception.class);
// StaticClass staticClassMock = mock(StaticClass.class); ??
mockStatic(StaticClass.class);
// when(..) and thenReturn(..) are static imports from PowerMockito library
when(StaticClass.methodA()).thenReturn("stubStringA");
when(StaticClass.methodB()).thenReturn("stubStringB");
doThrow(exception).when(param).setTimestamp(Mockito.any(XMLGregorianCalendar.class));
// Docs say method name can be inferred via reflection
Whitebox.invokeMethod(tested, event);
// this is where things are hairy. testedSpy is defined at the top level
verifyPrivate(testedSpy).pVMethod(testMock);
}
Ok, here is the answer:
In PowerMockito, if you want to verify the behavior of a private void method you use the verifyPrivate() method, but you have to do it like this:
verifyPrivate(tested).invoke("privateMethodName", argument);
Notice the use of the invoke method, missing from the last line of the OP.
NOTE: You do not have to use a doNothing().when(mock.privateMethod()) statement, because void methods in mock objects don't do anything by default.
example taken from here

Method invocation count Assertion

I've just started playing with PowerMock and EasyMock and I'm a bit confused about the way mocked method invocations are counted.
Example code:
class ClassToBeTested{
private boolean toBeMocked(Integer i){
return i%2==1;
}
}
And the test code:
#RunWith(PowerMockRunner.class)
#PrepareForTest(ClassToBeTested.class)
public class ClassToBeTestedTest{
private final Integer i=2;
ClassToBeTested underTest;
#Before
public void setUp() throws Exception {
underTest=PowerMock.createPartialMock(ClassToBeTested.class,
"toBeMocked");
PowerMock.expectPrivate(underTest, "toBeMocked", i)
.andReturn(true);
PowerMock.replay(underTest);
}
#Test
public dummyTest(){
Assert.assertTrue(underTest.toBeMocked(i);
//the call is: underTest.toBeMocked(2)
//so the computation is return 2%2==1; google says it 0 :)
//thus real method would return 0==1 (false)
//mocked one will return true, assertion should pass, that's ok
//RERUN ASSERTION
Assert.assertTrue(underTest.toBeMocked(i);
//method invocation count should be now 2
}
#After
public void tearDown() {
PowerMock.verify(underTest);
//WILL FAIL with exception saying
//the mocked method has not been called at all
//expected value (obvious) is one
}
And my question is, why does the mocked method invocation expectation fail?
Why verifying ClassUnderTest reveals that mocked method wasn't called at all?
It works for me, after changing the expect line to:
PowerMock.expectPrivate(underTest, "toBeMocked", i).andReturn(true).times(2);
Even without that change, it doesn't say the mocked mother wasn't called. It says
Unexpected method call toBeMocked(2):
toBeMocked(2): expected: 1, actual: 2
Are you using the most up to date PowerMock and EasyMock versions?

Categories