gpt4 book ai didi

android - 如何使用 RoboGuice 将依赖项注入(inject) Robolectric 测试类

转载 作者:太空狗 更新时间:2023-10-29 14:21:57 24 4
gpt4 key购买 nike

我想开始在我的 Android 应用程序中使用 Robolectric 和 RoboGuice。虽然我使用 Robolectric 取得了令人满意的进展,但我仍然无法使用 RoboGuice。我创建了一个用于试验的小型 Android 应用程序。它只有一个 Activity,注入(inject)一个 Button 并设置它的 OnClickListener。在相关的测试类中,我想注入(inject)这个 Activity ,以便能够测试按钮。我尝试了很多我在互联网上找到的东西,但这些都没有用,所以我在这里试一试。这是一些代码:

主要 Activity .java:

package com.example.TrialApp;

import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import roboguice.activity.RoboActivity;
import roboguice.inject.InjectView;

public class MainActivity extends RoboActivity implements View.OnClickListener {

@InjectView(R.id.main_LoginButton) private Button loginButton;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

loginButton.setOnClickListener(this);
}

@Override
public void onClick(View view) {
SharedPreferences.Editor editor;
if (view.getId() == R.id.main_Login_Button)
Log.i("Login-Button pressed... ", "");
}
}

CustomRobolectricTestRunner.java:

package com.example.TrialApp;

import com.xtremelabs.robolectric.RobolectricTestRunner;
import org.junit.runners.model.InitializationError;

import java.io.File;
public class CustomRobolectricTestRunner extends RobolectricTestRunner {
public CustomRobolectricTestRunner(Class testClass) throws InitializationError {
// defaults to "AndroidManifest.xml", "res" in the current directory
super(testClass, new File("TrialApp"));
}
}

MainActivity_Test.java:

package com.example.TrialApp;

import com.google.inject.Inject;
import com.xtremelabs.robolectric.Robolectric;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.assertNotNull;

@RunWith(CustomRobolectricTestRunner.class)
public class MainActivity_Test {

@Inject MainActivity mainActivity;
@Inject ClassWithoutAName classWithoutAName;

@Before
public void setUp() {

}

@Test
public void mainActivityShouldNotBeNull() {
assertNotNull(mainActivity);
}

@Test
public void classWithoutANameShouldNotBeNull() {
assertNotNull(classWithoutAName);
}
}

classWithoutAName 只是一个没有内容的非 Activity 类。我添加只是为了注入(inject)一个非 Activity 类。

运行 Test-Class 两个测试都失败并给出以下错误:

java.lang.AssertionError
at com.example.TrialApp.MainActivity_Test.mainActivityShouldNotBeNull(MainActivity_Test.java:33) <8 internal calls>
at com.xtremelabs.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:288) <16 internal calls>

java.lang.AssertionError
at com.example.TrialApp.MainActivity_Test.classWithoutANameShouldNotBeNull(MainActivity_Test.java:38) <8 internal calls>
at com.xtremelabs.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:288) <16 internal calls>

显然缺少了一些东西。在 MainActivity 中注入(inject)工作正常,应用程序正在运行。
为什么在 Robolectric-Testclass 中注入(inject)依赖项的相同模式不起作用?缺失的环节在哪里?
谢谢

最佳答案

在阅读了更多文章和主题后,我找到了部分解决方案。我仍然没有找到在测试类中注入(inject) UI 元素的方法,但我发现了如何在测试类中注入(inject)非 UI 元素。诀窍是实现一个扩展 AbstractModule 的“RobolectricTestModule”。在 roboguice.xml 中声明的模块中进行的绑定(bind)不存在于测试环境中,因此我们需要在这个额外模块中声明测试环境的绑定(bind)。在定制的 Testrunner 中,我们将 DefaultRoboModule 替换为新的 RobolectricTestModule。
ClassWithoutAName.java:

package com.example.TrialApp;

public class ClassWithoutAName {

private String string;

public ClassWithoutAName(String string) {
this.string = string;
}

public String getString() {
return string;
}
}

ClassWithoutANameProvider.java

package com.example.TrialApp.GuiceModules;

import com.example.TrialApp.ClassWithoutAName;
import com.google.inject.Provider;

public class ClassWithoutANameProvider implements Provider<ClassWithoutAName> {
@Override
public ClassWithoutAName get() {
return new ClassWithoutAName("testString");
}
}

ClassWithOutANameModule.java

package com.example.TrialApp.GuiceModules;

import com.example.TrialApp.ClassWithoutAName;
import com.google.inject.AbstractModule;

public class ClassWithOutANameModule extends AbstractModule {
@Override
protected void configure() {
bind(ClassWithoutAName.class).toProvider(ClassWithoutANameProvider.class);
}
}

RobolectricTestModule.java

package com.example.TrialApp.GuiceModules;

import com.example.TrialApp.WeirdThings;
import com.google.inject.AbstractModule;

public class RobolectricTestModule extends AbstractModule {
@Override
protected void configure() {
bind(ClassWithoutAName.class).toProvider(ClassWithoutANameProvider.class);
}
}

CustomRobolectricTestRunner.java

package com.example.TrialApp;

import android.app.Application;
import com.example.TrialApp.GuiceModules.RobolectricTestModule;
import com.xtremelabs.robolectric.Robolectric;
import com.xtremelabs.robolectric.RobolectricTestRunner;
import org.junit.runners.model.InitializationError;
import roboguice.RoboGuice;

import java.io.File;

public class CustomRobolectricTestRunner extends RobolectricTestRunner {

public CustomRobolectricTestRunner(Class testClass) throws InitializationError {
// defaults to "AndroidManifest.xml", "res" in the current directory
super(testClass, new File("TrialApp"));
}

@Override
public void prepareTest(Object test) {
Application application = (Application) Robolectric.application;

RoboGuice.setBaseApplicationInjector(application, RoboGuice.DEFAULT_STAGE,
RoboGuice.newDefaultRoboModule(application), new RobolectricTestModule());

RoboGuice.getInjector(application).injectMembers(test);
}
}

这就是非 UI 元素。

关于android - 如何使用 RoboGuice 将依赖项注入(inject) Robolectric 测试类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16046669/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com