19

我正在为一个依赖于通过 Intent 传递给它的附加功能的类编写一个 android Junit 测试。我能够让课程正常工作,但我仍然想知道如何为这样的课程编写单元测试,因为测试仍然失败。

public class AddClassEvent extends Activity{
 private String eventType;

  @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);

  Bundle extras = getIntent().getExtras();
  final String cNo = extras.getString("CourseNum");

  // create a model instance
  final StudentDBModel model = new StudentDBModel(this);

  setContentView(R.layout.add_class_event);
 .....
 .....
         }
     }

测试类看起来像......

public class AddClassEventTest extends ActivityInstrumentationTestCase2<AddClassEvent>{
 private StudentDBModel model = null;
 private RenamingDelegatingContext context = null;

 public AddClassEventTest() {
  super("com.UI", AddClassEvent.class);
 }

 /**
  * This method is called before each test.
  */
 @Override
 public void setUp() {
  context = new RenamingDelegatingContext(getActivity(), "test_");
  model = new StudentDBModel(context);
 }

 /*
  * This function will test addNewClassEvent() from StudentDBModel
  */
 public void testAddNewClassEvent(){

  ContentValues courseValues = new ContentValues();
  courseValues.put("CourseId", "60-415");
  courseValues.put("CourseName", "Advanced Database Design");
  courseValues.put("Section", "1");
  courseValues.put("Location", "Erie");
  courseValues.put("Credit", "3");
  courseValues.put("ProfEmail", "rfortier@uwindsor.ca");
  courseValues.put("Website", "cs.uwindsor.ca");

  model.addNewCourses(courseValues);

  int numEventsBefore = model.getNumClassEvents();

  ContentValues values = new ContentValues();

  values.put("EventName", "Assignment 1");
  values.put("CourseId", "60-415");
  values.put("EventType", "Assignment");
  values.put("EventWeight", "8");
  values.put("DueDate", "10/20/2010");

  model.addNewClassEvent(values);

  int numEventsAfter = model.getNumClassEvents();

  assertEquals(numEventsBefore + 1, numEventsAfter);
 }
}

问题是,我传递给 AddClassEvent 类的额外内容是我的数据库的 PK,它是在另一个类中创建并通过 Intent 传递给 AddClassEvent。每当我运行测试时,我都会在线获得一个 NULL 指针异常:

final String cNo = extras.getString("CourseNum");

如何从 Junit 测试中的额外内容创建信息?有没有办法让这个测试工作?我进行了广泛搜索,但找不到答案。是否有某种方法可以在 Junit 测试中错误地创建附加组件,使其认为它是由其他类创建的?如果是这样,有人可以告诉我怎么做吗?


好的,所以我已尝试听取您的建议,并将我的 setUp 功能更改为:

@Override
public void setUp() {
    context = new RenamingDelegatingContext(getActivity(), "test_");
    model = new StudentDBModel(context);
    Intent addEvent = new Intent();
    addEvent.setClassName("com.UI", "com.UI.AddClassEvent");
    addEvent.putExtra("CourseNum", "60-415");
    setActivityIntent(addEvent);
    getActivity();
}

但我仍然收到一个 NULL 指针异常。我的语法错了吗?有什么建议么?

4

2 回答 2

18

The class you inherit, ActivityInstrumentationTestCase2, allows you to mock Intents. From the documentation:

You can inject custom Intents into your Activity (see setActivityIntent(Intent)).

The documentation for setActivityIntent() further clarifies:

Call this method before the first call to getActivity() to inject a customized Intent into the Activity under test.

If you do not call this, the default intent will be provided. If you call this after your Activity has been started, it will have no effect.

So you should be able to place a call to this method inside your setUp() before your call to getActivity(). You can pass in a mocked Intent into setActivityIntent like you mentioned -- just build a fake Intent with extras that you'd expect the Activity to see.

于 2010-12-01T13:25:10.837 回答
12

好的,我发现了我的错误!setUp 的代码顺序错误。它应该看起来像:

@Override
public void setUp() {
    Intent addEvent = new Intent();
    addEvent.setClassName("com.UI", "com.UI.AddClassEvent");
    addEvent.putExtra("CourseNum", "60-415");
    setActivityIntent(addEvent);
    context = new RenamingDelegatingContext(getActivity(), "test_");
    model = new StudentDBModel(context);
}

我调用 getActivity() 两次,第一次调用在 Intent 之前。通过使用正确的顺序,测试运行良好。感谢 McStretch 的帮助。

于 2010-12-01T22:26:55.737 回答