Android   发布时间:2022-04-28  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了android – 如何用robolectric覆盖注入的@Singleton类?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个片段,我试图使用Robolectric(和mockito)测试,它使用@Singleton api类.我试图以一种可以自定义每个测试的响应的方式来模拟单例.这是我的片段引用的API类:

@Singleton
public class MyApi {
    @Inject
    public MyApi(Context context) {
        //Do something
    }

    public MyObject getMyFeed(){
    }
}

这是我正在尝试设置的测试类:

@RunWith(RobolectricTestRunner.class)
public class MyFragmentTest extends TESTCase {

    @Inject MyApiInterceptor myApi;
    @Inject Activity shadowActivity;
    @Inject LayoutInflater shadowLayoutInflator;
    @Inject ViewGroup shadowViewGroup;

    @Before
    public void setUp() throws Exception {
        Robolectric.bindShadowClass(SingleThreadActivity.class);
        ShadowApiModule module = new ShadowApiModule();
        Module roboGuiceModule = RoboGuice.newDefaultRoboModule(Robolectric.application);
        RoboGuice.setBaseApplicationInjector(Robolectric.application,RoboGuice.DEFAULT_STAGE,roboGuiceModulE);
        RoboInjector injector = RoboGuice.geTinjector(Robolectric.application);
        injector.injectMembers(this);
    }
    @After
    public void tearDown() {
        RoboGuice.util.reset();
        Application app = Robolectric.application;
        DefaultRoboModule defaultModule = RoboGuice.newDefaultRoboModule(app);
        RoboGuice.setBaseApplicationInjector(app,defaultModulE);
    }

    @Test
    public void testOnCreateView() throws Exception{

        myApi.mock = mock(MyApi.class);
        when(myApi.mock.getMyFeed()).thenReturn(new MyObject());

        MyFragment frag = new MyFragment();
        frag.onAttach(shadowActivity);
        frag.onCreate(null);
        frag.onCreateView(shadowLayoutInflator,shadowViewGroup,null);
        frag.onActivityCreated(null);
        frag.onStart();
        frag.onResume();
    }
}

@Singleton
class MyApiInterceptor extends MyApi
{
    public MyApi mock;

    @Inject
    public MyApiInterceptor(Context context) {
        super(context);
    }

    @Override
    public MyObject getMyFeed() throws Exception {
        return mock.getMyFeed();
    }
}
@Implements(Activity.class)
class SingleThreadActivity extends ShadowActivity{

    @Override
    public void runOnUiThread(Runnable action) {
        action.run();
    }
}

class ShadowApiModule extends AbstractModule {

    @Override
    protected void configure() {
        bind(Context.class).to(mockContext.class);
        bind(ViewGroup.class).toInstance(mock(ViewGroup.class));
        bind(MyApi.class).to(MyApiInterceptor.class);
    }
}

但是,当我运行测试时,我得到以下内容

com.google.inject.ConfigurationException: Guice configuration errors:

1) No implementation for android.view.ViewGroup was bound.
  while locating android.view.ViewGroup
    for field at com.mysource.MyFragmentTest.shadowViewGroup(UnkNown sourcE)
  while locating com.mysource.MyFragmentTest

1 error
    at com.google.inject.internal.InjectorImpl.getMembersInjector(InjectorImpl.java:952)
    at com.google.inject.internal.InjectorImpl.getMembersInjector(InjectorImpl.java:957)
    at com.google.inject.internal.InjectorImpl.injectMembers(InjectorImpl.java:943)
    at roboguice.inject.ContextScopedRoboInjector.injectMembersWithoutViews(ContextScopedRoboInjector.java:243)
    at roboguice.inject.ContextScopedRoboInjector.injectMembers(ContextScopedRoboInjector.java:236)
    at com.mysource.MyFragmentTest.setUp(RSSFeedActivityTest.java:58)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegaTingMethodAccessorImpl.invoke(DelegaTingMethodAccessorImpl.java:25)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
    at com.xtremelabs.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:292)
    at org.junit.runners.blockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
    at org.junit.runners.blockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
    at org.junit.runners.blockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:76)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

根据我对roboguice的理解,似乎由于某种原因它不能用ShadowViewGroup注入“shadowViewGroup”但我不确定为什么.如果我以错误的方式解决这个问题,那么请让我知道,但这似乎应该有效.

你能告诉我们:
1)为什么我的测试不起作用
 要么
 2)注入类使用的自定义单例的更好方法是什么?

解决方法

@H_673_29@ ViewGroup实现不可见.你在ShadowApiModule中声明它没有传递给RoboGuice.

代替:

@H_143_7@module roboGuiceModule = RoboGuice.newDefaultRoboModule(Robolectric.application);

试试这个:

@H_143_7@module roboGuiceModule = Modules.override(RoboGuice.newDefaultRoboModule(Robolectric.application)).with(new ShadowApiModule())

评论的答案:

如果你在测试中遇到单例问题,那就把它删除吧.应该隔离测试,因此不需要单独模式.

在生产代码中,而不是@Singleton类注释,在Module中设置与Singleton.class的绑定

bind(MyApi.class).to(MyApiImpl.class).in(Singleton.class);

对于测试模块,在您的ShadowModule案例中,设置不带Singleton的绑定.

bind(MyApi.class).to(MyApiImpl.class);

注入阴影类的另一种情况.您应该注入必须获取注入成员或具有不同实现的对象.除非有自定义实现的绑定,否则无需注入ViewGroup或Activity.

看看第一个Robolectric示例:http://pivotal.github.com/robolectric/只有构造函数,它的工作原理.

大佬总结

以上是大佬教程为你收集整理的android – 如何用robolectric覆盖注入的@Singleton类?全部内容,希望文章能够帮你解决android – 如何用robolectric覆盖注入的@Singleton类?所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。