Say my ContentProvider is called DogProvider. How do I set up my Instrumentation test skeleton? When I try to run the following, I always end up with a null MockContentResolver.
import org.junit.Test;
import org.junit.runner.RunWith;
import android.content.ContentProvider;
import android.database.Cursor;
import android.net.Uri;
import android.support.test.runner.AndroidJUnit4;
import android.support.test.filters.LargeTest;
import android.test.ProviderTestCase2;
import android.support.test.InstrumentationRegistry;
import android.test.mock.MockContentResolver;
import com.bus.proj.data.DogContract;
import com.bus.proj.data.DogProvider;
#RunWith(AndroidJUnit4.class)
#LargeTest
public class ContentProviderTest extends ProviderTestCase2<DogProvider>{
public ContentProviderTest() {
super(DogProvider.class, DogContract.CONTENT_AUTHORITY);
}
#Override
protected void setUp() throws Exception{
setContext(InstrumentationRegistry.getTargetContext());
super.setUp();
}
#Test
public void emptyQuery(){
MockContentResolver contentResolver = getMockContentResolver();
assertNotNull(contentResolver);//fail happens here
Uri uri = DogContract.DogEntry.CONTENT_URI;
Cursor cursor = contentResolver.query(uri,null,null,null,null);
}
}
In your test you're using the AndroidJunit4 test runner, which is based on annotation (compared to the JUnit3 which was based on method names).
This means that your setUp method is probably not called. For it to be called before each test, you need to use the #Before annotation, and make your method public :
#Before
#Override
public void setUp() throws Exception{
setContext(InstrumentationRegistry.getTargetContext());
super.setUp();
}
Related
The Unit Test code is attached:
import android.app.NotificationManager;
import android.app.NotificationManager.Policy;
import android.content.Context;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
#RunWith(AndroidJUnit4.class)
public class TestCase_com_cabooze_buzzoff__1592700345 {
#Test
public void testCase() throws Exception {
Context var1 = InstrumentationRegistry.getTargetContext();
Object var2 = var1.getSystemService("notification");
NotificationManager var3 = (NotificationManager)var2;
Policy var4 = var3.getNotificationPolicy();
}
}
I run the above code on sdk 21-29 and the results are :
21-22:NoSuchMethodError
23-27:SecurityException
28-29:success
The minSDKVersion of my apk is 21; targetSDKVersion is 30.
I am wondering why getNotificationPolicy will throw SecurityException on 23-27, considering the google doc yield that getNotificationPolicy need android.permission.ACCESS_NOTIFICATION_POLICY which is a normal permission. Besides, why it can run successfully on 28-29.
I get error "No instrumentation registered! Must run under a registering instrumentation" when I try to run SignUpFragmentTest class. I think thaterror is thrown when I use #Rule.
import android.support.test.runner.AndroidJUnit4;
import android.support.v4.app.Fragment;
import android.widget.FrameLayout;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import androidx.test.rule.ActivityTestRule;
import static junit.framework.Assert.assertNotNull;
#RunWith(AndroidJUnit4.class)
public class SignUpFragmentTest {
#Rule public final ActivityTestRule<LoginActivity> main = new ActivityTestRule<>(LoginActivity.class);
private LoginActivity mActivity = null;
#Before
public void setUp() throws Exception {
mActivity =main.getActivity();
}
#Test
public void testLaunchSingUpScreen(){
FrameLayout frameLayout = mActivity.findViewById(R.id.fragment_container);
assertNotNull(frameLayout);
Fragment fragment = new SignUpFragment();
mActivity.getSupportFragmentManager().beginTransaction().add(frameLayout.getId(),fragment).commitAllowingStateLoss();
}
#After
public void tearDown() throws Exception {
mActivity= null;
}
}
I add to dependencies:
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test:rules:1.1.1'
and
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
to defaultConfig
What worked for me is to completely change ALL libraries back from
androidX
to
com.android.support
libraries in the build.gradle
Please note: You might have to re import the libraries in test your class e.g.
import androidx.test.runner.AndroidJUnitRunner;
to
import android.support.test.runner.AndroidJUnitRunner;
Also make sure you always clean and rebuilt the project after each addition or removal library from build.gradle.
I am a bit new in testing, so bear with me.
I would like to test the behavior of onDismiss() method of mine. I would like to make sure that onDismiss() calls the showDialog() method for sure. In order to do this, I would like to verify is the mock in showDialog() being called or not.
I am getting an error message, saying there is no interaction with that mock. If I run it with deBug mode, I see we step on the loadingDialog.show() line, still I am getting this error.
Questions:
I would like to know, how can I test a subMethod call in this case?
Why is this happening?
(showDialog() is already covered by separate tests)
test:
sut.onDismiss(mockDialog)
verify(mockLoadingDialog, times(1)).show();
code:
public void onDismiss(DialogInterface dialog) {
showDialog();
}
public synchronized void showDialog() {
loadingDialog.show();
}
Error message: Actually, there were zero interactions with this mock.
package junit;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
#RunWith(MockitoJUnitRunner.class)
public class BasicTest {
#InjectMocks
private Basic basic;
#Mock
private LoadingDialog mockLoadingDialog;
#Mock
private DialogInterface dialog;
#Before
public void setUp() throws Exception {
}
#After
public void tearDown() throws Exception {
}
#Test
public void testOnDismiss() {
basic.onDismiss(dialog);
verify(mockLoadingDialog, times(1)).show();
}
}
Hope this helps!
Using #InjectMocks ensures that the mocks are injected wherever necessary and you do not have to init mocks in setup.
I have started learning about UIAutomator in eclipse based on http://university.utest.com/android-ui-testing-uiautomatorviewer-and-uiautomator/. When I wrote a simple code like this:
import static org.junit.Assert.*;
import com.android.uiautomator.core.UiDevice;
import com.android.uiautomator.core.UiObject;
import com.android.uiautomator.testrunner.UiAutomatorTestCase;
import com.android.uiautomator.core.UiSelector;
import com.android.uiautomator.core.UiObjectNotFoundException;
import com.android.uiautomator.core.UiScrollable;
import org.junit.Test;
public class test {
#Test
public void test() {
fail("Not yet implemented");
getUiDevice().pressHome();
}
}
I get error that getUIDevice() is undefined for the type test. How to improve this?
Your test class must extends UiAutomatorTestCase.
I have this test class...
package com.blah.blah;
import static org.junit.Assert.assertTrue;
import com.squareup.okhttp.mockwebserver.MockWebServer;
import java.io.IOException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
#Config(emulateSdk = 18)
#RunWith(RobolectricTestRunner.class)
public class IncompatibleClassChangeErrorTest {
private MockWebServer server;
#Before
public void setup() throws IOException {
server = new MockWebServer();
server.play();
}
#After
public void teardown() throws IOException {
server.shutdown(); // TODO Fix if possible. This throws java.lang.IncompatibleClassChangeError
}
#Test
public void test() {
assertTrue(true);
}
}
...and the following exception stack shows up in the consoles of both Eclipse and Android Studio...
Exception in thread "pool-2-thread-1" java.lang.IncompatibleClassChangeError: Class java.net.ServerSocket does not implement the requested interface java.io.Closeable
at com.squareup.okhttp.internal.Util.closeQuietly(Util.java:110)
at com.squareup.okhttp.mockwebserver.MockWebServer$2.run(MockWebServer.java:249)
at com.squareup.okhttp.mockwebserver.MockWebServer$4.run(MockWebServer.java:624)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:695)
...otherwise the test passes. Also running the test from the command line with Gradle just gives a Success message.
If I comment out the server.shutdown(), everything seems OK. Surely this can't be good though?
This seems to be the following issue that was fixed in 1.2.2
https://github.com/square/okhttp/issues/357
If you're using an earlier version, update to latest and see if it still happens.