Hi I really hope you can help me, I feel like I\'ve been pulling my hair out for days.
I\'m trying to write unit tests for a method A. Method A calls a static method
Static methods aren't related to any object - your helper.fetchUsernameFromInternet(...) is the same (but a bit confusing) as HelperUtils.fetchUsernameFromInternet(...) - you should even get a compiler warning due to this helper.fetchUsernameFromInternet.
What's more, instead of Mockito.mock to mock static methods you have to use: @RunWith(...), @PrepareForTest(...) and then PowerMockito.mockStatic(...) - complete example is here: PowerMockito mock single static method and return object
In other words - mocking static methods (and also constructors) is a bit tricky. Better solution is:
if you can change HelperUtils, make that method non-static and now you can mock HelperUtils with the usual Mockito.mock
if you can't change HelperUtils, create a wrapper class which delegates to the original HelperUtils, but doesn't have static methods, and then also use usual Mockito.mock (this idea is sometimes called "don't mock types you don't own")
You can use mockito latest version i.e 3.4.+ which allows static mocking
https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#48
I did this way using PowerMockito.
I am using AppUtils.class, it contains multiple static methods and functions.
Static function:
public static boolean isValidEmail(CharSequence target) {
return target != null && EMAIL_PATTERN.matcher(target).matches();
}
Test case:
@RunWith(PowerMockRunner.class)
@PrepareForTest({AppUtils.class})
public class AppUtilsTest {
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
PowerMockito.mockStatic(AppUtils.class);
PowerMockito.when(AppUtils.isValidEmail(anyString())).thenCallRealMethod();
}
@Test
public void testValidEmail() {
assertTrue(AppUtils.isValidEmail("name@email.com"));
}
@Test
public void testInvalidEmail1() {
assertFalse(AppUtils.isValidEmail("name@email..com"));
}
@Test
public void testInvalidEmail2() {
assertFalse(AppUtils.isValidEmail("@email.com"));
}
}
Edit 1:
Add following imports:
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
Hope this would help you.
Here are some solutions: