如何模拟 JSONObject?

How to mock JSONObject?

在一个方法的中间我正在做这样的事情

JSONObject = new JSONObject(json);

现在我正在尝试使用 Android StudioJUnit 对其进行单元测试。不幸的是,Android Studio 不允许我创建一个真实的 JSONObject 实例并要求我模拟它。

保留该代码并能够进行单元测试的最简单方法是什么?

Mockito 对我没有帮助,因为它无法模拟构造函数,但似乎 PowerMock 是可行的方法。

您可以使用简单的代码创建一个模拟 JSONObject

JSONObject mock = Mockito.mock(JSONObject.class);

然后您可以轻松地模拟它的方法,例如字段 getter,以便能够 return 从 JSONObject 中得到任何您想要的东西。

如果问题是这个 JSONObject 是在长函数的中间创建的,您可以将 JSONObject 创建提取给协作者,然后模拟协作者。

MyClass {
   MyClass(JSONObjectCreator creator) {
      this.creator = creator;
   }
   public void doesSomethingWithJSON(String input) {
      //...
      JSONObject jsonObject = creator.createJSONObject(input);
      //...
   }
}
JSONCreator {
   public JSONObject createJSONObject(String input) {
      return new JSONObject(input);
   }
}

在您的测试中,您将创建一个模拟 JSONObject,以及一个带有模拟 JSONObjectCreator 的新 MyClass。模拟的 JSONObjectCreator 将 return 模拟的 JSONObject。

我终于用上了Robolectric。它允许您 运行 模拟真实设备条件的测试。这使得无需模拟框架 类.

只需添加 robolectric 对 gradle 的引用并用 @RunWith(RobolectricTestRunner.class)

修饰我的测试 类

如果您使用的是 Kotlin 和 Mockk lib

private val json: JSONObject = mockk(relaxed = true)

在您的 InjectMock class 中有另一种获取 JSONObject 引用的方法,请参考下面的代码片段

import org.powermock.api.support.membermodification.MemberModifier;

private final Gson gson = new Gson();

@InjectMocks
private AppleService appleService;

MemberModifier.field(AppleService.class, "gson").set(appleService,gson);