I am getting the following exception when trying to mock the static method.
For SettingsUtility, static mocking is already registered in the
current thread To create a new mock, the existing static mock
registration must be deregistered
#Before
fun setUp() {
mockStatic(SettingsUtility::class.java) {
`when` { SettingsUtility.method(app) }.thenReturn { "" }}
}
The returned object's MockedStatic.close() method must be called upon completing the test or the mock will remain active on the current thread.
I am not sure if it is the same as how its done in Java. Hope this Java code snippet helps
private static MockedStatic<SettingsUtility> mockedSettings;
#BeforeAll
public static void init() {
mockedSettings = mockStatic(SettingsUtility.class);
}
#AfterAll
public static void close() {
mockedSettings.close();
}
Try doing this way, you will not get this error. It worked for me.
try(MockedStatic mocked = mockStatic(SettingsUtility.class)) {
mocked.when(SettingsUtility::method).thenReturn("whatever you want");
}
Building on #Sudha 's answer.
in Java you can use #BeforeClass and #AfterClass
private static MockedStatic<SettingsUtility> mockedSettings;
#BeforeClass
public static void init() {
mockedSettings = mockStatic(mockedSettings.class);
}
#AfterClass
public static void close() {
mockedSettings.close();
}
Mockito Inline works differently than the Mockito hence the failure. So what needs to be done is initialise and close the mocks explicitly.
You need to initialise the mockedStatic for your class
private MockedStatic<YourClassWithStaticMethod> mockedStatic;
Then add below code in BeforeEach and AfterEach
#BeforeEach
public void init() {
mockedStatic = mockStatic(YourClassWithStaticMethod.class);
}
#AfterEach
public void cleanup() {
mockedStatic.close();
}
And now you can set the mocked expectations.
mockedStatic.when(YourClassWithStaticMethod::staticMethodToMock).thenReturn(yourReturnedMockedObject);
I tried below and worked for me.
MockedStatic mockedStatic = mockStatic(SettingsUtility.class)
mocked.when(SettingsUtility::method).thenReturn("any thing");
...........
//do all stuf
and at last close the mock
mockedStatic.close();
Related
I have a method that checks a condition and does some work.
public void doSomeWork(){
if(!UtilityClass.someCondition()){
context.getmeSomething();
}
}
My test looks like this.
#Test
public void test(){
myClass.doSomeWork();
PowerMockito.verifyStatic(UtilityClass.class)
when(UtilityClass.someCondition()).thenReturn(false);
verify(mContext, times(1)).getmeSomething();
}
The problem is the stub is simply ignored. The test passes regardless of the stub result. By the same token, never verification on fails and I get Never wanted at the test but wanted at my class under test from Mockito. My question is why the boolean stub being ignored?
Update
I am not sure if it is significant with my original question, but the Utility class is included in the prepare for test and has mockStatic call in setUp.
Ordering of your statements!
Register your mocks and behaviour of it.
Call the method
Verify
EDIT:
you should also make sure, that UtilityClass is a mock. You can't stub actual classes, just mocks of them.
#Rule
public MockitoRule rule = MockitoJUnit.rule();
#Mock
private UtilityClass utilityClassMock;
private MyClass myClass;
#Before
public void beforeEachTest() {
myClass = new MyClass(utilityClassMock);
}
#Test
public void test(){
when(utilityClassMock.someCondition).thenReturn(false);
myClass.doSomeWork();
verify(mContext, times(1)).getmeSomething();
}
Just like GabrielJoerg said the stubbing should happen first before the method call. But the real issue here is that when stubbing, you should avoid calling verifyStatic. Here is what worked for me.
#Test
public void test(){
when(UtilityClass.someCondition()).thenReturn(false);
myClass.doSomeWork();
verify(mContext, times(1)).getmeSomething();
}
I've started learning android unit tests, but it looks very hard to find some good guides or information. Every example have a stupid example about 2+2 = 4
Say I write a little SDK which has few functions
MySdk.Init(Context context)
MySdk.CallTask()
I create an androidTest file
How should I call my SDK functions to check how they work? Somewhere required parameters like int/string/context. I just really don't understand, please help me.
This is what I've tried
public class AndroidTest {
private Activity context;
//default test
#Test
public void addition_correct() throws Exception {
assertEquals(4, 2 + 2);
}
#Test
public void checkContext() {
context = getActivity();
assertNotNull(context);
}
#Test
public void testInitPhase() {
MySdk.Init(context, new SdkInitializationListener() {
#Override
public void onInitializationSuccessful(String adv_id) {
assert (adv_id != null);
}
#Override
public void onInitializationError() {
}
});
}
}
For context i was tried context = new mockContext();. It's passed as context = null and my SDK failed with initialization.
Unit tests are mainly about testing an individual class in isolation, so that you can check if individual public methods of a class behave as you intend them to, and continue to do so if you change that class' code in the future. Let's say you have a class like this:
public class UtilityFunctions {
public int double(int value) {
return value * 2;
}
public String mirror(String value) {
if (value == null) return "";
return value + new StringBuilder(value).reverse().toString();
}
}
You want to test these two methods with:
valid input values, and check the output is as expected
invalid values, and check that errors are handled accordingly (and the correct exceptions thrown if necessary)
So a test class for the above class may look like this
#RunWith(JUnit4.class)
public class UtilityFunctionsTest {
private UtilityFunctions utility;
#Before
public void setUp() {
// Initialises any conditions before each test
utility = new UtilityFunctions();
}
#Test
public void testDoubleFunction() {
assertEquals(2, utility.double(1));
assertEquals(8, utility.double(4));
assertEquals(-12, utility.double(-6));
assertEquals(0, utility.double(0));
}
#Test
public void testMirror() {
assertEquals("", utility.mirror(null));
assertEquals("", utility.mirror(""));
assertEquals("aa", utility.mirror("a"));
assertEquals("MirrorrorriM", utility.mirror("Mirror"));
}
}
These standard Java unit tests are run from the test directory. However, you'll need to run tests in the androidTest directory whenever you're using Android-specific classes such as Context. If you're creating a MockContext, you're simply creating an empty Context whose methods don't do anything.
Without me knowing anything about what your MySDK does, I think you may need to pass a fully-functioning Context into your class for your tests. The Android JUnit runner does provide this with InstrumentationRegistry.getTargetContext(), so for your example, you may need to add this #Before method:
#Before
public void setUp() {
context = InstrumentationRegistry.getTargetContext();
}
You'll also need to remove the context = getActivity(); line from your first test.
I am new with tests.
I have something like next code and wish to cover it with unitTests using the Mockito:
public void doSomeJob(){
//some code before
getMvpView().execute(getObservable());
//some code after
}
private Observable<Boolean> getObservable(){
return Observable.create(new ObservableOnSubscribe<Boolean>() {
#Override
public void subscribe(#NonNull ObservableEmitter<Boolean> e) throws Exception {
Thread.sleep(5000);
e.onNext(true);
e.onComplete();
}
});
}
so questions:
how correct write test for getMvpView().execute(getObservable()); using Mokito?
how can i verify result of getObservable()?
If your private method is not a part of the interface, i.e. cannot be reached from outside the class, it's not something you should test (presumably it's not, since it's private). Mockito in turn doesn't provide mocking of private methods. Thereby you either need to change your interface (make this data available outside) or leave it without testing.
What you should test is the effect of calling the public methods of your class under test. If you do so you will be able to freely refactor the implementation details later, and your tests will still verify that your class works as expected.
I suppose that your code is part of a presenter implementation and the getMvpView() method returns a view interface:
public class MvpPresenterImpl {
private MvpView view;
public void doSomeJob(){
//some code before
getMvpView().execute(getObservable());
//some code after
}
public void attachView(MvpView view) {
this.view = view;
}
private MvpView getMvpView() {
return view;
}
private Observable<Boolean> getObservable(){
return Observable.create(new ObservableOnSubscribe<Boolean>() {
#Override
public void subscribe(#NonNull ObservableEmitter<Boolean> e) throws Exception {
Thread.sleep(5000);
e.onNext(true);
e.onComplete();
}
});
}
}
You can test the effect of doSomeJob() like so:
public class MvpPresenterImplTest {
private MvpPresenterImpl presenter;
private MvpView mockView;
#Before
public void setUp() throws Exception {
// Create a mock view instance so that we can verify method calls on it
mockView = mock(MvpView.class);
// Create our object under test, and set it up with the mock view
presenter = new MvpPresenterImpl();
presenter.attachView(mockView);
}
#Test
public void doSomeJob_callsExecuteOnViewWithCorrectObserver() throws Exception {
// What we want to test is the effect of invoking a public method.
presenter.doSomeJob();
// Verify that the execute method has been called by your class
// under test, and save the parameter for later.
ArgumentCaptor<Observable<Boolean>> paramCaptor =
ArgumentCaptor.<Observable<Boolean>>forClass((Class)Observable.class);
verify(mockView).execute(paramCaptor.capture());
// Get the actual observable that the execute method was called with.
Observable<Boolean> param = paramCaptor.getValue();
// Get a test observer so that we can check what our Observable emits
// (TestObserver is a built-in feature of RxJava, not Mockito.)
TestObserver<Boolean> test = param.test();
// Assert that the Observable behaves as expected
test.assertComplete();
test.assertResult(true);
}
}
I am learning how to unit-testing in android studio. as shown below, I would like to test the two methods shown below in the code section.
can you please help and guide me how to test this method?
code
public RequestCreator requestCreatorFromUrl(String mPicUrl)
{
return Picasso.with(mCtx).load(mPicUrl);
}
public void setImageOnImageView(RequestCreator requestCreator, ImageView mImagView)
{
requestCreator.into(mImagView);
}
My Attempts:
#Test
public void whenRequestCreatorFromUrlTest() throws Exception {
Picasso mockPicasso = mock(Picasso.class);
File mockFile = mock(File.class);
Assert.assertNotNull("returned Request creator is not null",
mockPicasso.load(mockFile));
}
First method you can't test, you'd have to verify the call of a static method which is not supported in Mockito.
You could split the method in
public RequestCreator requestCreator() {
return Picasso.with(mCtx);
}
and
public void load(RequestCreator requestCreator, String picUrl) {
requestCreator.load(picUrl)
}
and test the load(...) method.
Second method:
Mock the requestCreator. Mock the imageView.
Call the method with your mocked objects.
Then verify requestCreator.into(...) was called with the supplied parameter:
Mockito.verify(requestCreator).into(imageView);
I need to mock some static methods, that's fine so far and can be done like this:
#RunWith(PowerMockRunner.class)
#PrepareForTest({DataService.class})
public class PlayersAllViewModelTest {
// mock objects
private PlayersAllContextHandler mContextHandler;
private PlayersAllAdapter mAdapter;
#Before
public void setUp() throws Exception {
mockStatic(DataService.class);
//define mocks
mContextHandler = mock(PlayersAllContextHandler.class);
mAdapter = mock(PlayersAllAdapter.class);
}
#Test
public void check_init_requests_are_done() throws Exception {
// create instance of viewmodel
new PlayersAllViewModel(mContextHandler, mAdapter);
// check dataservice is requested for method 'getAllPlayers()'
PowerMockito.verifyStatic();
DataService.getAllPlayers(any(DataServiceCallback.class));
}
I need to test the behavior for a given response (success() / failure()) answered in a callback. The normal way to do so is like this:
// define mock answer
doAnswer(new Answer<MyCallback<String>>() {
#Override
public MyCallback answer(InvocationOnMock invocation) throws Throwable {
MyCallback<Player> callback = (MyCallback<Player>) invocation.getArguments()[0];
callback.onFailure(new UnsupportedOperationException());
return null;
}
}).when(>>mocked class instance<<).myTestMethod(any(MyCallback.class));
Because is want to call a static method, i can't do it like that so. There's no mocked instance of a class that could fill the gap :(
Does anybody know what's the correct way to do it?