I simply try to test the following part of my service method:
if (isDeleted) {
LoggingUtils.info("Deleted. ingredientUuuid: {}", ingredient.getUuid());
}
I try to use the following approach in order to catch the values passed to the static method:
// #RunWith(MockitoJUnitRunner.class)
#RunWith(PowerMockRunner.class)
public class DemoTest {
#Test
public void test() {
// code omitted
Page<IngredientDTO> result = ingredientService.findAll(request,sort);
PowerMockito.mockStatic(LoggingUtils.class);
ArgumentCaptor<String> arg1 = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<UUID> arg2 = ArgumentCaptor.forClass(UUID.class);
PowerMockito.verifyStatic(LoggingUtils.class, times(1));
LoggingUtils.info(arg1.capture(), arg2.capture());
// ...
}
}
When debugging the test, it throws "The class com.company.common.LoggingUtils not prepared for test." pointing the following line:
PowerMockito.mockStatic(LoggingUtils.class);
So, how can I fix this problem?
Late answer, sorry for that, but maybe it still helps: Maybe you simply forgot the #PrepareForTest for your static class?
// #RunWith(MockitoJUnitRunner.class)
#RunWith(PowerMockRunner.class)
#PrepareForTest(LoggingUtils.class) // <-- Required, otherwise you'll get exactly that "not prepared for test" error
public class DemoTest {
[...]
Related
Even though I have read the manual and gone through multiple answers for Powermock, could not mock a static method for my use case.
Class:
#Component
public class SCUtil{
public void createSC(){
try {
String host = InetAddress.getLocalHost().getHostAddress();
// ...
// ...
// ...
} catch (UnknownHostException e) {
log.error("Exception in creasting SC");
throw new ServiceException(e);
}
}
}
Test class:
#RunWith(PowerMockRunner.class)
#PrepareForTest( InetAddress.class )
public class SCUtilTest {
#InjectMocks
private SCUtil scUtil;
private Event event;
#Before
public void beforeEveryTest () {
event = new InterventionEvent();
}
#Test(expected = ServiceException.class)
public void testCreateSC_Exception () {
PowerMockito.mockStatic(InetAddress.class);
PowerMockito.when(InetAddress.getLocalHost()).thenThrow(new UnknownHostException("test"));
scUtil.createSC(event);
}
}
Here, the test is failing as no exception is being thrown:
java.lang.AssertionError: Expected exception:
com.example.v1.test.selftest.errorhandling.ServiceException
I have wrecked more than a couple of hours in this and still have not gotten it to work. What am I doing wrong?
Thank you for all the help in advance :)
java.net.InetAddress is a system class. The caller of the system class should be defined in #PrepareForTest({ClassThatCallsTheSystemClass.class}).
See documentation.
The way to go about mocking system classes are a bit different than
usual though. Normally you would prepare the class that contains the
static methods (let's call it X) you like to mock but because it's
impossible for PowerMock to prepare a system class for testing so
another approach has to be taken. So instead of preparing X you
prepare the class that calls the static methods in X!
Please note #InjectMocks annotation does not inject static mocks, it can be removed.
Example of working test:
#RunWith(PowerMockRunner.class)
#PrepareForTest(SCUtil.class)
public class SCUtilTest {
private SCUtil scUtil = new SCUtil();
#Test(expected = ServiceException.class)
public void testCreateSC_Exception () throws UnknownHostException {
PowerMockito.mockStatic(InetAddress.class);
PowerMockito.when(InetAddress.getLocalHost()).thenThrow(new UnknownHostException("test"));
scUtil.createSC();
}
}
I have this junit:
#RunWith(MockitoJUnitRunner.class)
public class SecurityManagerServiceTest {
#Mock
private SecurityManagerService securityManagerService = mock(SecurityManagerService.class);
#Test
public void testRequireAll() {
when(securityManagerService.loggerUser()).thenReturn(fakeUser());
doCallRealMethod().when(securityManagerService).requireRight(anyString());
//given(securityManagerService.restoreRight("a")).willThrow(SecurityException.class);
when(securityManagerService.restoreRight("a")).thenThrow(SecurityException.class);
}
but I have this error:
unnecessary Mockito stubbings
I also tried:
#Mock
private SecurityManagerService securityManagerService = mock(SecurityManagerService.class);
#Test
public void testRequireAll() {
when(securityManagerService.loggerUser()).thenReturn(fakeUser());
doCallRealMethod().when(securityManagerService).requireRight(anyString());
given(securityManagerService.restoreRight("a")).willThrow(SecurityException.class);
}
The problem is that you are stubbing, but not really testing anything. And if you are not testing anything, then there is no need for stubbing. That's why you have unnecessary Mockito stubbings.
I assume that you want to test your SecurityManagerService. If you want to do that, you need to create an instance or have a bean of that type, but not a mock. Then you call the method that you want to test and assert that you get the expected result.
If you expect to get an exception you can test it like this:
JUnit4, just enhance you #Test annotation:
#Test(expected=SecurityException.class)
JUnit 5:
#Test
void testExpectedException() {
Assertions.assertThrows(SecurityException.class, () -> {
//Code under test
});
}
I have a method that takes in the String, and check if it contains another string. If it does, then it throws a custom exception.
Class Test{
String s2="test";
public void testex(String s1){
if(s1.contains(s2))
throw new customException();
}
}
I am trying to write a unit test for this:
#Test (expected = customException.class){
when(s1.contains(s2)
.thenThrow(new customException());
}
However, my test is failing with the error as-- java.lang.Exception: Unexpected exception, expected customException but was<org.mockito.exceptions.misusing.MissingMethodInvocationException>
This test doesn't seem to be particularly useful, but I believe your issue is that Mockito's when() expects a method call for a mocked object.
#Test(expcted = CustomException.class)
public void testExMethod() {
#Mock
private Test test;
when(test.testEx()).thenThrow(CustomException.class);
test.testEx("test string");
}
I'm not quite following your example test. It looks like you're mocking your actual class with Mockito rather than writing a junit test. I would write a test like this:
With junit's assertThrows method:
#Test
void stringContainingThrowsError() {
Test myClassThatImTesting = new Test();
assertThrows(CustonException.class, () -> myClassThatImTesting.testex("test"))
}
With a normal assertion:
#Test
void stringContainingThrowsError() {
Test myClassThatImTesting = new Test();
try {
myClassThatImTesting.testex("test");
fail();
} catch (Exception ex) {
assertTrue(ex instanceof CustomException);
}
}
I am writing a JUnit test case for my code, but the Mockito is always returning null
#Component
public class ConnectorImpl {
public String returnString(String inte) {
String x = testing();
return x;
}
public String testing() {
return "test";
}
}
Test class
#RunWith(MockitoJUnitRunner.class)
public class ConnectorImplTest {
#Mock public ConnectorImpl connector;
#Test
public void testLoggedInRefill() throws Exception {
Mockito.when(connector.testing()).thenReturn("test");
String x = connector.returnString("8807");
assertEquals("8807", x);
}
}
When I am calling connector.returnString("8807");, it is always returning null. Is there anything I am doing wrong? I am new to JUnit.
One way you can test your method returnString is as :
// mock 'returnString' method call
Mockito.when(connector.returnString(anyString()).thenReturn("test");
// assert that you've mocked succesfully
assertEquals("test", connector.returnString("8807"));
According to your code, you are mocking your ConnectorImpl
So it is an empty object and it means that it is up to you to specifically when(...).then(...) any functionality that you like to test.
BTW - if you are testing the ConnectorImpl then you should not mock it, but actually use the real bean. You should mock the beans that ConnectorImpl is using.
So I would suggest your code look maybe like that:
#RunWith(MockitoJUnitRunner.class)
public class ConnectorImplTest {
public ConnectorImpl connector = new ConnectorImpl(...);
#Test
public void testLoggedInRefill() throws Exception {
String x = connector.returnString("8807");
assertEquals("8807", x);
}
}
You are mocking the object and you do not specify any behaviour for the returnString method of the mocked object. As you did for testing(), you can do the same for returnString() method:
when(connector.returnString(anyString())).thenReturn("text")
On the other hand why do you need ti mock this class?
I am writing unit test for methods to find banks near my location.
I mocked the class and tried to call the methods.
But, control is not going to method to execute it.
Below is unit test case.
#Test
public void testFindBanksByGeo() {
String spatialLocation = "45.36134,14.84400";
String Address = "Test Address";
String spatialLocation2 = "18.04706,38.78501";
// 'SearchClass' is class where 'target' method resides
SearchClass searchClass = Mockito.mock(SearchClass.class);
BankEntity bank = Mockito.mock(BankEntity.class);
// 'findAddressFromGeoLocation' and 'getGeo_location' to be mocked. They are called within 'target' method
when(searchClass.findAddressFromGeoLocation(anyString())).thenReturn(Address);
when(bank.getGeo_location()).thenReturn(spatialLocation2);
// 'writeResultInJson' is void method. so needed to 'spy' 'SearchClass'
SearchClass spy = Mockito.spy(SearchClass.class);
Mockito.doNothing().when(spy).writeResultInJson(anyObject(), anyString());
//This is test target method called. **Issue is control is not going into this method**
SearchedBanksEntity searchBanksEntity = searchClass.findNearbyBanksByGeoLocation(spatialLocation, 500);
assertNull(searchBankEntity);
}
What i have tried is also calling the real method on it,
Mockito.when(searchClass.findNearbyBanksByGeoLocation(anyString(), anyDouble())).thenCallRealMethod();
This calls real method but the methods i mocked above, are executing like real one. Means 'mocked methods' are not returning what i asked them to return.
So, what wrong i am doing here ?
why method is not executing?
The method is not getting called because you are calling it on a mock. You should call the method on an actual object.
Or you could use something like this before invoking the method.
Mockito.when(searchClass.findNearbyBanksByGeoLocation(Mockito.eq(spatialLocation), Mockito.eq(500))).thenCallRealMethod();
But I think this is not the way you should write the test. You shouldn't be mocking SearchClass in the first place. Instead there would be a dependency in SearchClass which gets you the address and geo location. You should be mocking that particular dependency.
OK, let's say we have this code:
class Foo {
// has a setter
SomeThing someThing;
int bar(int a) {
return someThing.compute(a + 3);
}
}
We want to test Foo#bar(), but there's a dependency to SomeThing, we can then use a mock:
#RunWith(MockitoJunitRunner.class)
class FooTest {
#Mock // Same as "someThing = Mockito.mock(SomeThing.class)"
private SomeThing someThing,
private final Foo foo;
#Before
public void setup() throws Exception {
foo = new Foo(); // our instance of Foo we will be testing
foo.setSomeThing(someThing); // we "inject" our mocked SomeThing
}
#Test
public void testFoo() throws Exception {
when(someThing.compute(anyInt()).thenReturn(2); // we define some behavior
assertEquals(2, foo.bar(5)); // test assertion
verify(someThing).compute(7); // verify behavior.
}
}
Using a mock we are able to avoid using a real SomeThing.
Some reading:
http://www.vogella.com/tutorials/Mockito/article.html
https://github.com/mockito/mockito/wiki