我想在Android-Apps中开始使用Robolectric和RoboGuice。虽然我使用Robolectric取得了令人满意的进展,但我仍然坚持使用RoboGuice。我创建了一个小型Android-App进行实验。它只有一个Activity,注入一个Button并设置它的OnClickListener。 在相关的Test-Class中我想要注入这个Activity,以便能够测试Button。我尝试了很多我在互联网上找到的东西,但这些都没有用,所以我试试看。 这是一些代码:
MainActivity.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类。我添加的只是为了注入一个非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中注入工作正常,应用程序正在运行
为什么在Robolectric-Testclass中注入依赖项的相同模式不起作用?丢失的链接在哪里?
谢谢
答案 0 :(得分:1)
在阅读了更多文章和帖子后,我找到了部分解决方案。我还没有找到在测试类中注入UI元素的方法,但我发现,如何在测试类中注入非UI元素。诀窍是实现扩展AbstractModule的“RobolectricTestModule”。在roboguice.xml中声明的模块中进行的绑定在测试环境中不存在,因此我们需要在此额外模块中声明测试环境的绑定。在定制的Testrunner中,我们用新的RobolectricTestModule替换DefaultRoboModule。
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元素。