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?
Related
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());
I am trying to use verify in a unit test to verify a method gets called on an object that is spied. I can verify the method is actually being called via a log statement and stepping through the code with a debugger. yet a verify(Object,1).method() call reports "Wanted but not invoked:" Also with the assertion uncommented mockTransferService.getCurrentTask() is returning null while again I can verify with the debugger that it is getting set.
Test code is shown below
#Test
public void testInitialPermitGranted() throws Exception {
Config mockConfig = mock(Config.class);
doReturn(path).when(mockConfig).getRequiredStringProperty(Config.WORK_DIR);
mockTransferService = spy(new TransferServiceImpl(mockServiceConnection, mockConfig,
Executors.newSingleThreadScheduledExecutor()));
doReturn(true).when(mockTransferService).doStartTransfer(any());
mockTransferService.enqueueTransfer(mockTransferTask);
Thread.sleep(1000);
//Assert.assertEquals(mockTransferTask, mockTransferService.getCurrentTask());
verify(mockTransferService,times(1)).startTransfer(any());
}
}
Method that is being tested is shown below
#Override
public boolean startTransfer(TransferTask transferTask) {
LOG.debug("StartTransferCalled");
setCurrentTask(transferTask);
return doStartTransfer(transferTask);
}
I'm pretty new to mockito and obviously I am missing something.
How can I test if a method does nothing. For example I have a static method that throws an exception if the given string-argument is null or empty (it's meant for argument-validation). Right now my tests look like this:
#Test
public void notNullOrEmpty_doesNothingIfValueIsNotNullOrEmpty() {
Require.notNullOrEmpty(Generate.randomString());
assertTrue(true); // <- this looks very ugly
}
#Test(expected = IllegalArgumentException.class)
public void notNullOrEmpty_throwsExceptionIfValueIsNull() {
Require.notNullOrEmpty(null);
}
#Test(expected = IllegalArgumentException.class)
public void notNullOrEmpty_throwsExceptionIfValueIsEmpty() {
Require.notNullOrEmpty("");
}
How can I make the first test to pass without calling assertTrue(true), there is a Assert.fail() is there something like an Assert.pass()?
EDIT:
Added missing (expected = IllegalArgumentException.class) to 3rd test
You have just to remove the assert in the first method.
#Test
public void notNullOrEmpty_doesNothingIfValueIsNotNullOrEmpty() {
Require.notNullOrEmpty(Generate.randomString());
// Test has passed
}
If the test method runs completely then it means it pass with success. Look at Eclipse junit output:
Update: as an additional comment, if you use Mockito framework you can leverage verify method to verify that a method was called X times. For instance, I used something like this:
verify(cmAlertDao, times(5)).save(any(CMAlert.class));
In your case, since you are testing static methods, then you might find useful using PowerMock which allows you to verify static methods (since Mockito doesn't). And you can use verifyStatic(...).
You should add #Test(expected = YourException.class) annotation.
Try to add to the first test:
#Test
public void notNullOrEmpty_doesNothingIfValueIsNotNullOrEmpty() {
String str = Generate.randomString();
Require.notNullOrEmpty(str);
assertNotNull(str);
}
and probably to you have better to rename it to notNullOrEmpty_doesNothingIfValueIsNotNullOrNotEmpty because you are testing it for not empty value.
A unit test must assert which is expected in the behavior of the method.
If in your specification, when your call notNullOrEmpty()no exception must be thrown when the data is valid and an exception must be thrown when the data is not valid so in your unit test you must do no assertion when the data is valid since if it doesn't success, a exception will be thrown and the test will so be in failure.
#Test
public void notNullOrEmpty_doesNothingIfValueIsNotNullOrEmpty() {
Require.notNullOrEmpty(Generate.randomString());
}
I have a simple JUnit test. It fails, unless I have called the relevant function previously.
FAILS:
#Test public void isTotalSuccess(){
writer.calculateStats();
Assert.assertFalse(writer.isTotalSuccess());
}
PASSES and displays "TotalSuccess is false":
#Test public void isTotalSuccess(){
writer.calculateStats();
// One additional line here
System.out.println("TotalSuccess is " + writer.isTotalSuccess());
Assert.assertFalse(writer.isTotalSuccess());
}
I don't understand why this is happening, since usually nested methods/functions are evaluated first, before their enclosing function.
Please explain why the test fails unless the method being tested has already been called once. Is this behaviour specific to JUnit, or have I missed something really obvious?
More information:
These tests are part of WriterTest, which is testing Writer
writer is declared as a field of WriterTest with private static Writer writer = new Writer();
writer.isTotalSuccess() is a very simple method:
public boolean isTotalSuccess() {
if (total == success){
return true;
}
return false;
}
This is my first day writing Unit tests using Mockito and I might have started with a complex exercise.
Below is my class structure and I am writing tests for Class2.targetMethod(). Class1 static method modifies passed in object instead of returning any results.
class Class1 {
static void dbquery(OutParam out) {
// Complex code to fill in db results in OutParam object
}
}
class Class2 {
void targetMethod() {
OutParam p1 = new OutParam1();
Class1.dbquery(p1);
ResultSet rs = p1.getCursor();
...
}
}
Below is my setup for the tests:
#RunWith(PowerMockRunner.class)
#PrepareForTest({Class1.class, Class2.class})
public class Class2Test {
#Before
public void setUp() throws Exception {
PowerMockito.mockStatic(Class1.class);
doAnswer(new Answer<Void>() {
#Override
public Void answer(InvocationOnMock invocation) throws Exception {
OutParam result = (OutParam)invocation.getArguments()[1];
OutParam spy = spy(result);
ResultSet mockResult = mock(ResultSet.class);
doReturn(mockResult).when(spy.getCursor());
when(mockResult.getString("some_id")).thenReturn("first_id","second_id");
when(mockResult.getString("name")).thenReturn("name1","name2");
return null;
}
}).when(Class1.class, "dbquery", any());
}
}
However the tests fail with exception below - mainly due to "doReturn" line.
Any suggestions on this problem or if my approach is completely wrong.
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
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
The syntax for:
doReturn(mockResult).when(spy.getCursor());
should be:
doReturn(mockResult).when(spy).getCursor();
By calling when with only the spy, and not spy.getCursor(), you give Mockito a chance to temporarily deactivate getCursor so you can stub it without calling the real thing. Though that doesn't seem to be important here, Mockito insists that you keep this pattern for calls to when following doAnswer (etc).