1

我正在尝试 ShadowClass Crashlytics/Fabric,以便 Robotlectric 3 测试不会失败。我到目前为止是这样的:

为 Fabric 添加 Shadow 类的自定义测试运行器:

public class TestRunner extends RobolectricGradleTestRunner {
    public TestRunner(Class<?> klass) throws InitializationError {
        super(klass);
    }

    @Override
    protected ShadowMap createShadowMap() {
        return super.createShadowMap()
            .newBuilder().addShadowClass(ShadowFabric.class).build();
    }

    @Override
    public InstrumentationConfiguration createClassLoaderConfig() {
        InstrumentationConfiguration.Builder builder = InstrumentationConfiguration.newBuilder();
        builder.addInstrumentedClass(ShadowFabric.class.getName());
        return builder.build();
    }
}

Fabric 的影子类:

@Implements(Fabric.class)
public class ShadowFabric {
    @Implementation
    public static Fabric with(Context context, Kit... kits) {
        System.out.println("Shadowing Fabric");
        return null;
    }
}

我的应用程序的应用程序类:

public class MyApp extends Application {
    @Override
    public void onCreate() {
        setupCrashlytics();
    }
    protected void setupCrashlytics() {
        Crashlytics crashlyticsKit = new Crashlytics.Builder().core(new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build()).build();
        // Initialize Fabric with the debug-disabled crashlytics.
        Fabric.with(this, crashlyticsKit);
    }
}

这是在 Debug 中通过的测试(因为 Crashlytics 在其上被禁用),但在发布模式下失败,因为 ShadowClass 无法正常工作:

@RunWith(TestRunner.class)
@Config(constants = BuildConfig.class, sdk=21, packageName="com.my.release.package.name", shadows={ShadowFabric.class})
public class MyTest {
    @Test
    public void testGreenDAOsave() {
        // blah
    }
}

我在测试期间使用 Crashlytics / Fabric 遇到的错误如下:

STANDARD_ERROR
io.fabric.sdk.android.services.concurrency.UnmetDependencyException: com.crashlytics.android.core.CrashlyticsMissingDependencyException:
This app relies on Crashlytics. Please sign up for access at https://fabric.io/sign_up
install an Android build tool and ask a team member to invite you to this app's organization.

堆栈跟踪显示正在调用 MyApp.setupCrashlytics() 并且 Fabric.with() 失败。

1) 是的,该应用程序已向 Crashlytics 注册。

2) 是的,我确实联系了 Crashlytics 支持电子邮件。有人告诉我“不支持 Robolectric”。

据我所知,我只需要让影子类的东西工作,然后 Crashlytics 就会被隐藏而不是初始化。

想法/帮助将不胜感激!

4

1 回答 1

3

这是我通常建议如何针对不可测试的东西编写测试。

将您的Fabric初始化提取到受保护的方法:

public class <MyApplicationName> {

public void onCreate() {
   initFabric();
}

@VisibileForTesting
void initFabric() {
....
}
}

在测试源中创建Test<MayApplicationName>类(相同的包并覆盖Fabric初始化:

public class Test<MyApplicationName> {
void initFabric() {
//nothing to do
}
}

在任何需要使用Fabric的地方都使用 DI(依赖注入)在测试中模拟Fabric 。更重要的是,我建议您创建 Analytics/Crash/Distribution 类并在整个应用程序中隐藏Fabric的使用。

最后,您留下了包装/隐藏Fabric的类。在这里,您可以编写自定义阴影、监视真实对象或不对其进行测试。而且您已经尝试编写自定义阴影但没有成功,此外,间谍也不是这里的选择。

快乐编码!

于 2016-05-02T10:36:44.420 回答