7

我想测试一个CommentActivity通常构造和使用实例的 Android 活动CommentsDataSource(两者都是我编写的类)。

public class CommentActivity extends Activity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    :
    CommentsDataSource = new CommentsDataSource(..);
    :
  }
  :
}

我愿意创建MockCommentsDataSource自己,并希望避免使用第三方模拟框架。(为什么?因为我是一名教师,试图减少我需要在学期中填满的信息量以及我的学生需要安装的软件数量。我看过其他推荐 Guice、roboguice 和 Spring 的帖子。)

我的问题是如何将CommentsDataSource(或MockCommentsDataSource)传递给活动。Serializable制作它们或似乎不切实际Parcelable,它们必须是它们才能通过Intentthat 开始传递CommentActivity。虽然我可以轻松地传入调试标志,但使用它需要CommentActivity了解MockCommentsDataSource,这实际上与它无关(并且在单独的应用程序中):

public class CommentActivity extends Activity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    :
    debugMode = getIntent().getBooleanExtra(DEBUG_MODE, false);

    // Get a connection to the database.
    final CommentsDataSource cds = (debugMode ? 
      new MockCommentsDataSource() :   // Abstraction violation
      new CommentsDataSource(this));
      :
   }
   :
}

我应该如何MockCommentsDataSource注入CommentActivity?FWIW,我正在使用 Eclipse 并正在为最新的 SDK 版本进行开发。

我想到的一种解决方案是使用抽象工厂模式,因为使工厂可序列化相对容易。考虑到我的限制,这是最好的方法吗?

4

2 回答 2

1

这里有两个想法:

不使用工厂:

这可能仅适用于单元测试而不适用于集成测试:

  1. 创建一个返回 CommentsDataSource 的方法,例如 getCommentsDataSource()
  2. 创建一个继承 CommentActivity 的类
  3. 使用返回 MockCommentsDataSource 的方法覆盖 getCommentsDataSource()
  4. 测试新类

使用工厂:

正如您所提到的,您可以更改 CommentActivity 代码以从工厂方法获取 CommentsDataSource。这样你就可以让工厂方法返回模拟类。

希望这可以帮助!

于 2014-05-29T09:17:47.357 回答
0

我提供了一个简单而丑陋的解决方案,使用私有静态字段来注入依赖项:

private static Client client;

并使用反射从测试中设置字段值:

public static void setStaticFieldValue(final Class<?> clazz, 
        final String name, final Object value) throws Exception {
    final Field field = clazz.getDeclaredField(name);
    field.setAccessible(true);
    field.set(null, value);
}

然后,在 ieonCreate()中,如果设置了该字段,则使用该“注入”测试实例,否则使用常规测试实例。

丑陋,但只需要对被测类进行与测试相关的少量更改。

于 2015-09-08T16:57:15.153 回答