Android 单元测试中使用Robolectric的模拟RESTAPI调用
大家好,我在单元测试中使用Robolectric、Mockito和Mockito,我需要验证依赖于api请求调用的数据 如何编写代码,以便在运行单元测试时RESTAPI调用将使用模拟数据 在StockFragment.java中,我使用SpringAndroid+Robospice执行RESTAPI调用。 另外,我在片段中有一个来自Robospice的RequestListener,如果请求成功与否,它会更新片段中的UI 这是我的片段:Android 单元测试中使用Robolectric的模拟RESTAPI调用,android,unit-testing,android-fragments,robolectric,spring-android,Android,Unit Testing,Android Fragments,Robolectric,Spring Android,大家好,我在单元测试中使用Robolectric、Mockito和Mockito,我需要验证依赖于api请求调用的数据 如何编写代码,以便在运行单元测试时RESTAPI调用将使用模拟数据 在StockFragment.java中,我使用SpringAndroid+Robospice执行RESTAPI调用。 另外,我在片段中有一个来自Robospice的RequestListener,如果请求成功与否,它会更新片段中的UI 这是我的片段: public class StockFragment
public class StockFragment extends RoboDialogFragment {
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.my_layout, container, false);
return view;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
displayStockInfo();
}
private void displayStockInfo(){
request = new MyRequest();
request.setQuote(getStock().getSymbol());
lastRequestCacheKey = request.createCacheKey();
((BaseActivity)getActivity()).getSpiceManager().execute(request, lastRequestCacheKey, DurationInMillis.ALWAYS_EXPIRED, new MyRequestListener());
}
private class MyRequestListener implements RequestListener<PseStocksResponse> {
@Override
public void onRequestFailure(SpiceException e) {
//show toast about failure reason ...
}
@Override
public void onRequestSuccess(PseStocksResponse pseStocksResponse) {
//UPDATE UI VIEWS ...
}
}
}
我正在考虑的一个解决方案是在StockFragment中使用testMode标志,并执行一些条件语句,如果为true,这些语句将返回测试数据,但我认为有一种更好的测试方法。
我想我需要在我的测试类上监听Http请求并捕获该请求,然后提供模拟数据,不过我不确定。
注:Robolectric已设置,并已确认正常工作和测试。虽然我没有在上面的代码片段中包含它们。
Roboguice也被用作注入。我鼓励您使用像Dagger这样的依赖注入框架。弄清楚这个框架是如何工作的可能需要很长时间。看看例子 我还鼓励您从视图中删除网络逻辑。让它保持活跃 此外,我还可以选择性地隐藏关于特定网络框架(RoboSpice)使用的概念 至于现在,您可以通过下一步修复测试 使用Robolectric运行测试:
@RunWith( RobolectricTestRunner.class )
@Config( reportSdk = 18, emulateSdk = 18 )
public class StockFragmentTest {...}
为SpiceManager添加模拟:
创建测试活动:
public class StockFragmentTest
{
...
public class TestBaseActivity extends BaseActivity
{
@Override
SpiceManager getSpiceManager()
{
return mockedSpiceManager;
}
}
}
@Before
public void setUp()
{
...
stockFragment = new StockFragment();
FragmentTestUtil.startVisibleFragment( stockFragment, TestBaseActivity.class, <id of placeholder in xml for BaseActivity> );
...
}
使用测试活动:
public class StockFragmentTest
{
...
public class TestBaseActivity extends BaseActivity
{
@Override
SpiceManager getSpiceManager()
{
return mockedSpiceManager;
}
}
}
@Before
public void setUp()
{
...
stockFragment = new StockFragment();
FragmentTestUtil.startVisibleFragment( stockFragment, TestBaseActivity.class, <id of placeholder in xml for BaseActivity> );
...
}
我认为最后一段代码不适用于您的代码。你可能有股票交易。因此,您应该通过类比来创建TestStockActivity,并替换BaseTestActivity的用法。然而,我预计这种方法会产生更多的副作用。适当的依赖注入将有助于Robolectric已经包含一个虚假的http层,您可以在其中准备答案
详细信息和示例可在的答案中找到,我将避免修改代码以了解测试存在性这也将因ClassCastException而失败,因为FragmentTestUtil将尝试将片段附加到活动实例,而不是BaseActivity,但在此之前,它将因StubException而失败,因为您需要使用RobolectrictTestRunneRobolectric设置正确,不会因异常而失败,我只是没有将其包含在上面的代码中。对于ClassCastException,你的建议是什么?嗨,尤金,你是对的ClassCastException发生了。我用Roboguice打针。您能否提供包含更多详细信息或教程的资源/文章的链接?这个概念对我来说仍然太宽泛了。下面是如何将RoboGuice与片段一起使用:下面是如何进行POJO注入:下面是如何定义绑定:下面是如何在测试中覆盖注入: