private void mockStorageServiceFactory(StorageGroupService storageGroupService)
throws StorageServiceException {
PowerMockito.mockStatic(StorageServiceFactory.class);
PowerMockito.when(StorageServiceFactory.getContainerNameForPartner(anyLong()))
.thenReturn("dummyName");
}
Actual method is getting called at 3rd line (when().thenReturn()).
I have already added #RunWith(PowerMockRunner.class) and #PrepareForTest annotations.
Why actual method is called? I tried PowerMockito.doReturn also, but getting same issue.
Sorry, I was running the test case from main method. When i ran it as JUNIT, it is working.
Related
public String getMongoDBName() throws Exception {
return mongoConnectionDetails.getMongoDatabase().getName();
}
mongoConnectionDetails custom class is Autowired here.
What I tried is
Mock (mongoDboperation);
when(mongoConnectionDetails.getMongoDatabase().getName()).thenReturn("dbName");
String output = mongoDboperation.getMongoDBName();
assertEquals (output, "actualDBname");
But SONAR is still showing it as RED uncovered lines. Please help. Thanks !
You're not getting coverage for this method, because you're running the test with a mock object. This means you are only testing the mock, not the original class.
In general, in the tests for a particular class, you should never mock the class that is being tested. Only mock collaborators of that class (in this case, mongoConnectionDetails.
I'm new to using Powermockito to mock static methods. My first attempt is to mock calls on the Environment class. I have a sample test that exemplifies my problem as shown in my test class below. The test is failing, so I'm seeking some help.
#RunWith(PowerMockRunner.class)
#PrepareForTest({Environment.class})
public class StorageUtilsTest {
#Test
#Config(sdk = 22)
public void myTest() {
PowerMockito.mockStatic(Environment.class);
File mockStorageDirectoryFile = Mockito.mock(File.class);
PowerMockito.when(Environment.getExternalStorageState()).thenReturn(Environment.MEDIA_MOUNTED);
PowerMockito.when(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)).thenReturn(mockStorageDirectoryFile)`;
}
}
I'm trying to mock the static method call to Environment.getExternalStoragePublicDirectory and it returns null giving an exception org.mockito.exceptions.misusing.NotAMockException: Argument should be a mock, but is: class java.lang.Class. The static method call is returning null. I understand that the method call is deprecated in sdk=29, so I've configured the test to run with sdk=22, and it still didn't work. So in an attempt to understand what was going on, I added a call to the getExternalStorageState method as shown above. I get a null return value on this method too. My understanding is that this method should return something, but it also returns null. I'm configuring the test for sdk=22 since I'm setting a targetSdkVersion 29 in my build.gradle.
I'm really confused as to why I can't mock the static methods on the Environment class. Will someone please help me understand what I'm doing wrong?
I want to unit test Java code that calls System.exit(-1) and want it to just do nothing instead of exiting the process. The underlying reason is that otherwise JaCoCo does not work properly and project guidelines want to see that line covered. Changing the tested code is not an option, too. Other calls to System should work normally. PowerMockito 2.0.7 is already used in the project and should be used here, too. My current Java version is 1.8.0_181 on Windows.
I tried with
PowerMockito.spy(System.class);
PowerMockito.doNothing().when(System.class, "exit", ArgumentMatchers.any(int.class));
//here comes the code under test that calls System.exit
It does not seem to work, System.exit seems to exit the process anyway.
How do it get this to work?
I think you should replace both the lines in your sample code
PowerMockito.spy(System.class);
PowerMockito.doNothing.....
to
PowerMockito.mockStatic(System.class);
This change works in my local as System.exit does nothing because of the mock on static method.
Also, I hope you are using PrepareForTest annotation
#PrepareForTest(CLASS_UNDER_TEST)
The spy method is to call real methods and have some wrapper around the non-static methods. Since you need a mock for static methods, mockStatic method should be used instead.
Update 1
The PowerMockito mockStatic method by default creates mock for all the static methods within the class. I don't have any clean solution. But, I can suggest a solution which looks ugly but does what is needed i.e only mock specific static method and remaining methods are invoking real methods. PoweMockito's mockStatic method is internally calling DefaultMockCreator to mock the static methods.
#RunWith(PowerMockRunner.class)
public class StaticTest {
#Test
public void testMethod() throws Exception {
// Get static methods for which mock is needed
Method exitMethod = System.class.getMethod("exit", int.class);
Method[] methodsToMock = new Method[] {exitMethod};
// Create mock for only those static methods
DefaultMockCreator.mock(System.class, true, false, null, null, methodsToMock);
System.exit(-1); // This will be mocked
System.out.println(System.currentTimeMillis()); // This will call up real methods
}
}
As per the PowerMockito documentation, the right way to call static void method is -
PowerMockito.mockStatic(SomeClass.class);
PowerMockito.doNothing().when(SomeClass.class);
SomeClass.someVoidMethod();
Reference - https://github.com/powermock/powermock/wiki/Mockito#how-to-stub-void-static-method-to-throw-exception
This should create the mock behaviour for the specific static void method. Unfortunately, this doesn't work for System Class because System class is final. Had it been not final, this would have worked. I tried it and I got this exception -
org.mockito.exceptions.base.MockitoException:
Cannot mock/spy class java.lang.System
Mockito cannot mock/spy because :
- final class
Code -
#Test
public void testMethod() throws Exception {
PowerMockito.mockStatic(System.class);
PowerMockito.doNothing().when(System.class);
System.exit(-1); // mockito error coming here
System.exit(-1);
System.currentTimeMillis();
}
I've created the following test method where I mock Settings.Secure and stub the getString method of that class.
#Test
public void testIsDevicePostOwner() throws Exception {
String mockDeviceId = "2c3977ad-0867-49d6-aad8-c2762f373551";
Post mockedPost = mock(Post.class);
Settings.Secure mockedSecure = mock(Settings.Secure.class);
ContentResolver mockContentResolver = mock(ContentResolver.class);
when(mockedSecure.getString(mockContentResolver, Settings.Secure.ANDROID_ID)).thenReturn(mockDeviceId);
}
When I run the test I get the following error:
java.lang.RuntimeException: Method getString in android.provider.Settings$Secure not mocked.
Does anybody have any ideas?
If you want to mock an static method, use PowerMock
You'll need to run with PowerMockRunner and Prepare the class for test:
#PrepareForTest({Settings.Secure.class})
For mocking the object you need to:
PowerMockito.mockStatic(Settings.Secure.class);
Then you could try:
when(Settings.Secure.getString(mockContentResolver, Settings.Secure.ANDROID_ID)).thenReturn(mockDeviceId);
Finally, you could test:
verifyStatic();
Try adding
testOptions {
unitTests.returnDefaultValues = true
}
in your build.gradle
More info here http://tools.android.com/tech-docs/unit-testing-support
Settings.Secure.getString is a static method, so mock(Settings.Secure.class) won't mock it. Even subclassing Settings.Secure and creating your own static getString won't help here.
I'm not sure if there's any reflection magic that can help you out in this case; none comes to mind.
I have a very strange problem, when i try to run a JUnit test with multiple test case, it will only pass the first test case and shown IndexOut of Bound error
public class ABCTest {
#Test
public void basicTest1(){...}
#Test
public void basicTest2(){...}
...
but if i commend the rest test case, test them one by one, it will pass all of them.
public class ABCTest {
#Test
public void basicTest1(){...}
//#Test
//public void basicTest2(){...}
//...
Since you do not provide the complete testcase and implementation class, I have to make some assumptions.
Most likely you are mutating the state of the tested object by the testcase.
Usually you try to get a clean test fixture for each unit test. This works by having a method with the #Before annotation which creates a new instance of the class under test. (This was called 'setUp()' in older versions of junit.)
This ensures that the order of test method execution as well as the number of executions does not matter and each method is working isolated.
Look at what you are doing inside of the test case and see if you are changing data that may be used by the other test cases and not restoring it to the original state. For example you have a text file that you read and write to in basicTest1 that you then read again in basicTest2 but assume the file is the same as it was before you ran basicTest1.
This is just one possible problem. would need to see the code for more insight