Here is my unit test. Somehow when I create instantiate SpannableStringBuilder instance with a non-null string argument, it appears to be null. What's wrong with this code?
public class CardNumberTextWatcherTest {
private CardNumberTextWatcher watcher;
#Before
public void setUp() throws Exception {
watcher = new CardNumberTextWatcher();
}
#Test
public void afterTextChanged_cardNumberDividedWithSpaces() {
assertTransformText("1111222233334444", "1111 2222 3333 4444");
}
private void assertTransformText(final String testStr,
final String expectedStr) {
final CardNumberTextWatcher watcher = new CardNumberTextWatcher();
final Editable actualStr = new SpannableStringBuilder(testStr);
// When I debug I see that actualStr value is null. Therefore test
//doesn't pass. What's the problem?
watcher.transformText(actualStr);
assertEquals(expectedStr, actualStr.toString());
}
}
The problem was in the testing directory. As soon as SpannableStringBuilder is a part of Android SDK, it couldn't be resolved in regular JUnit test directory. When I moved my class to androidTest directory, everything started to work as expected.
#RunWith(RobolectricTestRunner::class)
Using Robolectric resolves the issue.
You are calling actualStr.toString() which is what the assertion is comparing with, not actualStr itself so look for routes through SpannableStringBuilder to see what could result in null from toString(). Probably testStr is null.
Related
Programming Language : Java
Testing tool : powermockito,Junit
I have a static block in my code. I am using that code particle as several reference. While during integration testing (using powermockito) I mocked a getWebDetails() method in the below example. The method for mocking (getWebDetails) is also getting called from the static block in my program, so it excecutes before my test gets excecuted and returns a null value. I need to assign values to xml contents during my testing.
class test1{
private static String xmlcontents;
static {
xmlcontents= ServiceUtils.getWebDetails();
}
public static String getWebDetails() throws Exception{
url = test2.getURL();
return url;
}
}
Nota bene (please note): I tried using #SuppressStaticInitializationFor("test1"), but it suppresses all the static methods inside the class.
Can anyone help me? Any help will be highly appreciable..
[UPDATE]:
I know what NPE is,but I don't know why it appears here.So I think this is totally not a duplicated question as What is a Null Pointer Exception, and how do I fix it?.But any way I have found the answer.To use Mockito in instrumented test,addition dependencies dexmaker and dexmaker-mockito are also required:
androidTestCompile "com.google.dexmaker:dexmaker:1.2"
androidTestCompile "com.google.dexmaker:dexmaker-mockito:1.2"
And if you don't run yout test under MockitoJUnitRunner,addition initialization is also required as below answer has mentioned:
MockitoAnnotations.initMocks(this);
See also Initialising mock objects - MockIto for futher discussion.
I want to write a simple test that checks if user's data is shown on the UI.The Activity retrieves the data stored in sharedPreferences within onResume() and shows it on the UI.The following is my code for the test:
#RunWith(AndroidJUnit4.class)
public class EditProfileActivityTest {
#Mock
private UserPreference userPreference;
private String FAKE_NAME = "Test";
#Rule
public ActivityTestRule<EditProfileActivity> activityTestRule = new ActivityTestRule(EditProfileActivity.class,true,false);
#Before
public void setUp(){
//Set fake SharedPreferences
when(userPreference.getName()).thenReturn(FAKE_NAME);
//Start Activity
Intent intent = new Intent();
activityTestRule.launchActivity(intent);
}
#Test
public void showUserData() throws Exception{
onView(withId(R.id.name_tv)).check(matches(withText(FAKE_NAME)));
}
}
where UserPreference is a custom class which simply wraps SharedPreference class and contains lots of getters and setters.This is its constructor
public UserPreference(Context context) {
this.context = context;
sharedPreferences = this.context.getSharedPreferences("Pref", Context.MODE_PRIVATE);
prefEditor = sharedPreferences.edit();
}
and one of its getter
public String getName() {
return sharedPreferences.getString(context.getString(R.string.pref_name), "Guest");
}
But when I run the test,it keeps showing NullPointerExceptiions on this line
when(userPreference.getName()).thenReturn(FAKE_NAME);
I've searched for related topics but I still can't see why.I think the concept of mock is to re-define a method's behavior no matter what the real implementation is. I am new to testing,so I am sorry in advance if this is a silly qustion.
By the way the test runs perfectly with the following code
#RunWith(AndroidJUnit4.class)
public class EditProfileActivityTest {
private UserPreference userPreference;
private String FAKE_NAME = "Test";
#Rule
public ActivityTestRule<EditProfileActivity> activityTestRule = new ActivityTestRule(EditProfileActivity.class,true,false);
#Before
public void setUp(){
//Start Activity
Intent intent = new Intent();
activityTestRule.launchActivity(intent);
}
#Test
public void showUserData() throws Exception{
onView(withId(R.id.name_tv)).check(matches(withText(FAKE_NAME)));
}
}
But the preference data it retrieves is from the "real" device.In this case i can't make an assertion about what will be displayed so I can't tell whether the test is passed.This is why I want to mock the preference to make it predictable.
You have to init your mocks in #Before like so:
public void setUp() {
MockitoAnnotations.initMocks(this);
// ...
}
Your userPreference object is null, but you're trying to call a method on it. If you post all of your code it will be easier.
The idea of a Mock object is correct - but you're not using a Mock object, you're calling when() on a real object, but which hasn't been created yet, thus the NPE.
I'm building a Wicket 1.6 application.
In this I have a Parameter class and a FillParameter class to translate org.apache.wicket.PageParameters to my own Parameter class. The Parameter class has defaults (which are set during creation), the FillParameter has min/max values I check on. Both the default values as the min/max values are loaded from a text_resource.properties file using StringResourceModel.
example (line 15):
private int offset = Integer.parseInt((new StringResourceModel("bla.bla.bla.offset", null)).getString());
So far so good. This is working fine in my Wicket application.
Now I'm working on my junit tests and I want to test my FillParameters.class. This is a snippet from my current FillParametersTest.class:
private WicketTester wicketTester;
#Mock
Localizer localizer = mock(Localizer.class);
#Before
public void init() {
wicketTester = new WicketTester(MyApplication.class);
when(localizer.getString(eq("bla.bla.bla.offset"), (Component)anyObject(), anyString())).thenReturn("0");
wicketTester.getApplication().getResourceSettings().setLocalizer(localizer);
}
#Test
public void fillParametersGoodTest() {
PageParameters pageParameters = new PageParameters("pOffset=0");
Parameters parameters = FillParameters.fillParameters(pageParameters, parameters);
Assert.assertEquals(parameters.getOffset(), 0);
}
Alas, this is not working. The test seems to find the resource, but it doesn't get the value from that resource, resulting in:
java.lang.NumberFormatException: null
at java.lang.Integer.parseInt(Integer.java:454)
at java.lang.Integer.parseInt(Integer.java:527)
at bla.bla.bla.Parameters.<init>(Parameters.java:15)
at bla.bla.bla.FillParametersTest.fillParametersGoodTest(FillParametersTest.java:63)
(line 15 in Parameters is the example I've mentioned above)
I've been searching for a solution to my problem, but I can only find good examples on how to read from a resource in the test class, not how to make it work in a application class called by the test class.
I hope I've made my problem clear, and that someone can help me with it. I'm quite new to wicket, but eager to learn.
Problem: how can I read text_resources during junit test with StringResourceModel?
Answer 27 feb 2015
Ok, so I've refactored my whole application and now I've got the code working, and it's actually very simple
private WicketTester wicketTester;
#Before
public void init() {
tester = new WicketTester(MyApplication.class);
}
#Test
public void fillParametersGoodTest() {
MockRequestParameters pageParameters = new MockRequestParameters();
pageParameters.addParameterValue("offset", "0");
FillParameters fp = new FillParameters();
Parameters parameters = fpo.fillParameters(pageParameters, parameters);
Assert.assertEquals(parameters.getOffset(), 0);
}
I'm pretty sure the problem is in your Mockito rule (the when):
when(localizer.getString(eq("bla.bla.bla.offset"), (Component)anyObject(), anyString())).thenReturn("0");
It doesn't match the real call and thus later the value is null.
Play in this area.
I have problem mock whenNew(File.class) using PowerMockito. Here is my method I want to test:
public void foo() {
File tmpFile = new File("Folder");
if (!tmpFile.exists()) {
if (!configFolder.mkdir()) {
throw new RuntimeException("Can't create folder");
}
}
File oneFileInFolder = new File(tmpFile, "fileOne.txt");
if (oneFileInFolder.exists()){
//do something
}
}
Here is test code I wrote:
static File mockFile;
#Before
public void setUp() throws Exception {
//....some code
mockFolder = mock(File.class);
when(mockFolder.getPath()).thenReturn("Folder");
when(mockFolder.exists()).thenReturn(true);
whenNew(File.class).withParameterTypes(String.class).withArguments(anyString()).thenReturn(mockFolder);
//...some code
}
But when I debug my testcase, I still see a real folder created in my pwd. I don't want folders created when I run my testcases. Any idea?
Since you haven't specified this in your question, the following may be missing:
#PrepareForTest(ClassYoureCreatingTheFileInstanceIn.class)
According to the Wiki:
Note that you must prepare the class creating the new instance of MyClass for test, not the MyClass itself. E.g. if the class doing new MyClass() is called X then you'd have to do #PrepareForTest(X.class) in order for whenNew to work.
In other words, X is the class that contains foo() in your example.
I am newbie to Java and facing below issue. I have following code:
public class ReadExcel {
Config conf = new Config();
String filePath = conf.getInputfilePath();
#Test
public void readFullXL() {
try {
FileInputStream FSRead = new FileInputStream(filePath);
I have declared this variable ‘filePath’ outside function because; I want to use it as global variable.
However, inside readFullXL(), I am not able to get value for variable ‘filePath’ and getting null pointer exception.
Can somebody suggest? How I can declare global variable in Junit file.
Edit:
Of course first you gotta check that your getInputfilePath() method does not return null.
Further: I suggest you go ahead and read some informations on UnitTesting (JUnit - Tutorial).
If it's just one test you could just instantiate your needed classes within that test.
#Test
public void readFullXL() {
Config conf = new Config();
FileInputStream FSRead = new FileInputStream(conf.getInputfilePath());
//...
}
If you have multiple tests relying on the same fixture you can go ahead and implement a setup method using the #Before annotation. The setup method will then be called before every test (#Test annotation) method.
class ReadExcel {
Config conf;
#Before
public void setUp() {
conf = new Config();
}
#Test
public void readFullXL() {
//...
FileInputStream FSRead = new FileInputStream(conf.getInputfilePath());
// Run your test
}
}
Thank you for your response and time.
I got it working by creating interface between config and ReadExcel file.
Also removed Junit test annotation from config file that was not required.
Thanks,
Ashvini