gpt4 book ai didi

android - 一些 Robolectric 测试在一起运行时失败但单独通过

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:11:31 26 4
gpt4 key购买 nike

我使用的是 Android Studio 1.2,Robolectric 3.0-rc2。

我有两个测试类,一个叫MotdTest使用一种测试 POJO json 序列化和反序列化的测试方法。另一个叫UserInfoTest ,其中包含 4 个测试方法,用于测试我设置到 SharedPreferences 中的用户信息.如果我运行 UserInfoTest单独地,所有 4 种测试方法总是通过。但是,如果我运行所有测试,则测试在 MotdTest 中成功,但是 UserInfoTest 的两种方法总是失败。我现在通过调用 ./gradlew test 从命令行运行

有谁知道为什么当我运行所有测试时我的一些测试失败了?在我的 UserInfoTest 中,我确实有一个 @After我通过在 SharedPreferences.Editor 上调用 clear().commit() 来进行清理的注释方法.

用户信息测试:

testOnSignIn()assertThat(6, equalTo(prefs.getAll().size())); 处失败因为 prefs 的大小为 0。

testIsSignedIn()assertThat(UserInfo.isSignedIn(), is(false)); 处失败

@RunWith(MyRoboRunner.class)
@Config(constants = BuildConfig.class)
public class UserInfoTest {

private String mExpectedId;

private String mExpectedName;

private String mExpectedEmail;

private String mExpectedToken;

private String mExpectedKey;

@Before
public void setUp() throws Exception {
ShadowLog.stream = System.out;

mExpectedId = "someiD";
mExpectedName = "johnny boy";
mExpectedEmail = "some@email.com";
mExpectedToken = "Session Token";
mExpectedKey = "Session Key";
}

@After
public void tearDown() {
SharedPreferences prefs = RuntimeEnvironment.application.getSharedPreferences(
UserInfo.PREFERENCES, Context.MODE_PRIVATE);
prefs.edit().clear().commit();
mExpectedId = null;
mExpectedName = null;
mExpectedEmail = null;
mExpectedToken = null;
mExpectedKey = null;
}

@Test
public void testOnSignIn() {
SharedPreferences prefs = RuntimeEnvironment.application.getSharedPreferences(
UserInfo.PREFERENCES, Context.MODE_PRIVATE);

UserInfo.onSignIn(mExpectedId, mExpectedName, mExpectedEmail, mExpectedKey, mExpectedToken);
assertThat(mExpectedKey, equalTo(UserInfo.getSessionKey()));

assertThat(mExpectedToken, equalTo(UserInfo.getSessionToken()));
assertThat(mExpectedId, equalTo(UserInfo.getUserId()));
assertThat(mExpectedEmail, equalTo(UserInfo.getUserEmail()));
assertThat(mExpectedName, equalTo(UserInfo.getUserName()));

assertThat(6, equalTo(prefs.getAll().size()));
}

@Test
public void testOnSignOut() {
UserInfo.onSignIn(mExpectedId, mExpectedName, mExpectedEmail, mExpectedKey, mExpectedToken);
// Set Over21 to make sure we unset this value on Signout
UserInfo.setIsOver21(true);

UserInfo.onSignOut();
SharedPreferences prefs = RuntimeEnvironment.application.getSharedPreferences(
UserInfo.PREFERENCES, Context.MODE_PRIVATE);
assertThat(UserInfo.getSessionKey(), nullValue());
assertThat(UserInfo.getSessionToken(), nullValue());
assertThat(UserInfo.isOver21Set(), is(false));
assertThat(prefs.getAll().size(), equalTo(0));
}

@Test
public void testIsSignedIn() {
assertThat(UserInfo.isSignedIn(), is(false));

UserInfo.onSignIn(mExpectedId, mExpectedName, mExpectedEmail, mExpectedKey, mExpectedToken);
assertThat(UserInfo.isSignedIn(), is(true));

UserInfo.onSignOut();
assertThat(UserInfo.isSignedIn(), is(false));
}

@Test
public void testIsOver21Set() {
assertThat(UserInfo.isOver21Set(), is(false));
UserInfo.setIsOver21(false);
assertThat(UserInfo.isOver21Set(), is(true));
}
}

用户信息:

App是一个 Application子类和App.getInstance()是单例。

private static final SharedPreferences PREFS = App.getInstance()
.getSharedPreferences(PREFERENCES, Context.MODE_PRIVATE);

public static void onSignIn(String userId, String fullName, String email, String sessionKey,
String sessionToken) {
SharedPreferences.Editor editor = PREFS.edit();
editor.putString(PROPERTY_USER_ID, userId);
editor.putString(PROPERTY_USER_NAME, fullName);
editor.putString(PROPERTY_USER_EMAIL, email);
editor.putString(PROPERTY_SESSION_KEY, sessionKey);
editor.putString(PROPERTY_SESSION_TOKEN, sessionToken);
editor.putStringSet(PROPERTY_PENDING_SCANS, new HashSet<String>());

editor.commit();
}
public static boolean isSignedIn() {
return getSessionToken() != null;
}

MyRoboRunner:this 的修改版本因为我在 mac 上,也因为我在我的项目中以 API 22 为目标,但 robolectric 还不支持那个,所以我针对 API 21 运行我的测试。

public class MyRoboRunner extends RobolectricGradleTestRunner {

public MyRoboRunner(Class<?> klass) throws InitializationError {
super(klass);
}

protected AndroidManifest getAppManifest(Config config) {
AndroidManifest appManifest = super.getAppManifest(config);
String moduleRoot = getModuleRootPath(config);

//can use this line instead dynamic path resolution when AS bug is fix, or use @Config
//FsFile androidManifestFile = appManifest.getAndroidManifestFile();
FsFile androidManifestFile = FileFsFile.from(moduleRoot,
appManifest.getAndroidManifestFile().getPath()
.replace("bundles", "manifests/full"));
FsFile resDirectory = FileFsFile.from(moduleRoot, appManifest.getResDirectory().getPath());
FsFile assetsDirectory = FileFsFile
.from(moduleRoot, appManifest.getAssetsDirectory().getPath());
return new AndroidManifest(androidManifestFile, resDirectory, assetsDirectory) {
@Override
public int getTargetSdkVersion() {
//lollipop bc it's highest that robolectric 3.0 supports
return Build.VERSION_CODES.LOLLIPOP;
}

@Override
public int getMinSdkVersion() {
return Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1;
}
};
}

private String getModuleRootPath(Config config) {
String moduleRoot = config.constants().getResource("").toString().replace("file:", "");
return moduleRoot.substring(0, moduleRoot.indexOf("/build"));
}
}

最佳答案

您在 PREFS 中保留对 SharedPreferences 的静态引用。我认为只要您在 tearDown 方法中重置它或完全删除静态引用,您的测试就会得到修复。如果您删除静态引用,则 SharedPreferences 文件将由 Robolectric 本身清除 - 无需在tearDown 中再次清除它。

还有一点要提 - 我也在使用 Mac 并且我对 RobolectricGradleTestRunnner 没有任何问题。有时我必须在运行测试之前运行 clean,但别无其他。

还有你提到的另一件事 robobolectric-gradle-plugin。 Android Studio v1.1+ 和 android gradle plugin v1.1+ 不需要它

关于android - 一些 Robolectric 测试在一起运行时失败但单独通过,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30061576/

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