Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android JUnit tests can't call any android api?

From Android's Testing Fundamentals, "You can use plain JUnit to test a class that doesn't call the Android API, or Android's JUnit extensions to test Android components." I believe that's why spanString in the following test is null. Can someone confirm that is the reason?

import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class SpanPainterTest {
  @Test
  public void appliesColorPerRange () {
    SpannablesString spanString = new SpannableString("Aa Bb");
    SpanPainter painter = new SpanPainter(new ForegroundColorSpan(10));
    SpannableString coloredSpan = 
      painter.applyColor(spanString, new Pair<Integer, Integer>(0,1));
    ForegroundColorSpan[] colorArr = 
      coloredSpan.getSpans(0,0, ForegroundColorSpan.class);
    assertEquals(10, colorArr[0]);
  }
}

Here's SpanPainter.java

public class SpanPainter {
  ForegroundColorSpan color;
  public SpanPainter (ForegroundColorSpan color) {
    this.color = color;
  }

  public SpannableString applyColor(SpannableString span,  
                                    Pair<Integer, Integer> pair) {
    span.setSpan(color,pair.first, pair.second, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
    return span;
  }
}

But it says "Use Android's JUnit extension to test android components. So I extend AndroidTestCase, but spanString still equals null. This makes me think that no unit test can use an android api object without it being set to null. Is that right? (That's my second question.)This is the SpanPainter test as an AndroidTestCase, which resulted in spanString = null.

public class SpanPainterTest extends AndroidTestCase {
  @SmallTest
  public void testAppliesColorPerRange () {
    SpannableString spanString = new SpannableString("Aa Bb");
    SpanPainter painter = new SpanPainter(new ForegroundColorSpan(10));
    ...same as above.
    assertEquals(9, colorArr[0]);
  }
} 

Those are my two JUnit questions. If I don't extend AndroidTestCase, then will using any object in the android api result in null. And if I extend AndroidTestCase will any object from the android api be automatically set to null.

like image 320
flobacca Avatar asked Aug 12 '15 19:08

flobacca


1 Answers

I was running into a similar problem with a SpannableStringBuilder. My problem was solved by moving my test to the androidTest directory. (Thanks to this answer for the suggestion.)

enter image description here

Here is the test in the new location:

/**
 * Instrumentation test, which will execute on an Android device.
 *
 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 */
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {

    @Test
    public void myStringTest() throws Exception {
        CharSequence unicode = "";
        MyClass myClass = new MyClass(unicode); 
        CharSequence result = myClass.getUnicodeText(); // uses SpannableStringBuilder internally
        CharSequence expected = unicode;
        assertEquals(expected, result);
    }
}

Note

You can also try mocking the Android classes, but this was a lot easier for a Testing beginner like me. The disadvantage, I suppose, is that the instrumentation tests run slower than Unit tests.

like image 165
Suragch Avatar answered Sep 30 '22 14:09

Suragch