【问题标题】:Robolectric's Shadow Object and MockingRobolectric 的阴影对象和模拟
【发布时间】:2013-11-15 09:36:20
【问题描述】:

我对移动设备上的单元测试非常陌生。我想为 Android 移动应用程序编写 JUnit 测试。我遇到了Robolectric,它正在 IDE 中进行测试(对我来说,Eclipse)

但我真的不明白 Robolectric 的影子对象。我应该将它们用作嘲弄吗? ShadowActivity等这些Shadow对象的使用目的是什么?

例如,我在几乎每个 Activity 类的 onCreate 方法中都有 Crashlytics、Google Analytics 代码。当遇到这些行时,Robolectric 会抛出错误。 ShadowActivity 能解决这些类型的问题吗?

很抱歉,但正如我所说,我是单元测试的新手,Robolectric 文档对初学者没有帮助。

【问题讨论】:

    标签: java android unit-testing junit robolectric


    【解决方案1】:

    但我真的不明白 Robolectric 的影子对象。我是不是该 拿它们当嘲讽?这些Shadow对象的使用目的是什么 像 ShadowActivity 等?

    阴影有点像模拟或存根,但并不完全相同。阴影的存在是为了添加额外的方法,这些方法可以在测试中用于检查底层 Android 对象的状态。例如,许多 Android 对象具有特定值的 setter,但没有 getter。我们可以将 getter 添加到阴影中,并在测试中使用它们来断言底层对象。

    例如,我在 onCreate 中有 Crashlytics、Google Analytics 代码 几乎每个 Activity 类中的方法。 Robolectric 抛出错误时 它遇到了这些行。 ShadowActivity 能解决这些问题吗 问题类型?

    可能不会。为此,您应该使用依赖注入将 Crashlytics 或 GoogleAnalytics 的虚假版本注入您的测试。

    Robolectric 的目的是伪造足够多的 Android 平台,让您能够 在您的桌面 JVM 上运行测试 - 而不是模拟 Android。仍然可以使用良好的工程实践,例如依赖注入或模拟。

    很抱歉,正如我所说,我是单元测试的新手 Robolectric 文档对初学者没有帮助。

    我同意。我们正在努力让它变得更好,但我们还有很长的路要走。

    【讨论】:

      【解决方案2】:

      关于:

      例如,我在 onCreate 中有 Crashlytics、Google Analytics 代码 几乎每个 Activity 类中的方法。 Robolectric 抛出错误时 它遇到了这些行。 ShadowActivity 能解决这些问题吗 问题类型?

      您可以将对库的调用封装在实现某种 AnalyticsFacade 的 Facade 实现中,并创建一个封装所有实现的类,并将常见行为委托给它们。

          public interface Analytics{
      
          void sendEvent(String category, String action, Map<String,String> params);
      
          void log(String msg);
      }
      
      public class AnalyticsFacade implements Analytics{
          private List<Analytics> analyticsServices;
      
          public AnalyticsFacade()
          {
              this.analyticsServices = new ArrayList<Analytics>();
          }
      
          public void addAnalyticsService(Analytics analytics){
              analyticsServices.add(analytics);
          }
      
          @Override
          public void sendEvent(String category, String action, Map<String, String> params)
          {
              for(Analytics service: analyticsServices){
                  service.sendEvent(category,action,params);
              }
          }
      
          @Override
          public void log(String msg)
          {
              for(Analytics service: analyticsServices){
                  service.log(msg);
              } 
          }
      }
      
      public class GoogleAnalytics implements  Analytics{
      
          private Tracker tracker;
      
          public GoogleAnalytics(Tracker tracker)
          {
              this.tracker = tracker;
          }
      
          @Override
          public void sendEvent(String category, String action, Map<String, String> params)
          {
              //Note that this method signature has changed since GA v2 , now you pass a Map and
              //it has a builder in order to create it
              tracker.send(category,action,params);
          }
      
          @Override
          public void log(String msg)
          {
              throw new RuntimeException("Not implemented");
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2015-09-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-05
        • 2020-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多