gpt4 book ai didi

android - Mockito:如何将 getString 与 mockito 一起使用?

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

我从谷歌关于如何测试您的 SharedPreferences 的示例中获得灵感通过创建 SharedPreferencesHelper 在此处编码类:

https://github.com/googlesamples/android-https://github.com/googlesamples/android-testing/blob/master/unit/BasicSample/app/src/main/java/com/example/android/testing/unittesting/BasicSample/SharedPreferencesHelper.java

您可以看到该类使用类中硬编码的实际字符串作为 sharedPreferences 的键。 - 这是类(class)的摘录:

public class SharedPreferencesHelper {

// Keys for saving values in SharedPreferences.
static final String KEY_NAME = "key_name";
static final String KEY_DOB = "key_dob_millis";
static final String KEY_EMAIL = "key_email";

public boolean savePersonalInfo(SharedPreferenceEntry sharedPreferenceEntry){
// Start a SharedPreferences transaction.
SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putString(KEY_NAME, sharedPreferenceEntry.getName());
editor.putLong(KEY_DOB, sharedPreferenceEntry.getDateOfBirth().getTimeInMillis());
editor.putString(KEY_EMAIL, sharedPreferenceEntry.getEmail());

// Commit changes to SharedPreferences.
return editor.commit();
}

在使用他们的 SharedPreferencesHelperTest 进行测试时在这里上课,他们访问模拟的 sharedPreferences使用上述类中定义的相同变量:

https://github.com/googlesamples/android-testing/blob/master/unit/BasicSample/app/src/test/java/com/example/android/testing/unittesting/BasicSample/SharedPreferencesHelperTest.java

该类的摘录如下所示:

when(mMockSharedPreferences.getString(eq(SharedPreferencesHelper.KEY_NAME), anyString()))
.thenReturn(mSharedPreferenceEntry.getName());
when(mMockSharedPreferences.getString(eq(SharedPreferencesHelper.KEY_EMAIL), anyString()))
.thenReturn(mSharedPreferenceEntry.getEmail());
when(mMockSharedPreferences.getLong(eq(SharedPreferencesHelper.KEY_DOB), anyLong()))
.thenReturn(mSharedPreferenceEntry.getDateOfBirth().getTimeInMillis());

谷歌这样做的方式允许他们绕过使用 context 的问题从 string.xml 资源文件中拉出一个字符串并在 sharedPreferences 中查询它就像通常使用 getString() 发生的情况一样,即:

mSharedPreferences.getString(context.getString(R.string.name),"");

但是,我读到不可能使用 context.getString因为它是一个 final 方法,mockito 不能模拟 final 方法:

Mockito - Overriding a method that takes primitive parameters

然后我如何使用 mockito 对 getString 的任何方法进行单元测试? ?任何带有 getString 的方法将不起作用,我的单元测试将失败。

这是我为 SharedPreferences 编写的类(class)我想用 sharedPreferences 测试它用 getStrings 编写的键:

public class SharedPreferencesHelper {

// The injected SharedPreferences implementation to use for persistence.
private final SharedPreferences mSharedPreferences;
private Context context;

public SharedPreferencesHelper(SharedPreferences sharedPreferences, Context context) {
mSharedPreferences = sharedPreferences;
this.context = context;
}

public boolean saveName(String name) {
// Start a SharedPreferences transaction.
SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putString(context.getString(R.string.name), name);
return editor.commit();
}

public String fetchName() {
// Start a SharedPreferences transaction.
return mSharedPreferences.getString(context.getString(R.string.name),"");
}

public boolean saveGender(String gender) {
SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putString(context.getString(R.string.gender), gender);
return editor.commit();
}

}

这是我为上述类编写的测试 - 它与谷歌的 SharedPreferencesHelperTest 非常相似:

@RunWith(MockitoJUnitRunner.class)
public class SharedPreferencesHelperTest {

private static final String TEST_NAME = "Test name";

private SharedPreferencesHelper mMockSharedPreferencesHelper;

@Mock
SharedPreferences mMockSharedPreferences;
@Mock
SharedPreferences.Editor mMockEditor;
@Mock
MockContext context;

@Before
public void setUp() throws Exception {
// Create a mocked SharedPreferences.
mMockSharedPreferencesHelper = createMockSharedPreference();
}

@Test
public void testSaveName() throws Exception {
boolean success = mMockSharedPreferencesHelper.saveName(TEST_NAME);
Timber.e("success " + success);
assertThat("Checking that name was saved... returns true = " + success,
success, is(true));
String name = mMockSharedPreferencesHelper.fetchName();
Timber.e("name " + name);
assertThat("Checking that name has been persisted and read correctly " + name,
TEST_NAME,
is(name));
}

/**
* Creates a mocked SharedPreferences.
*/
private SharedPreferencesHelper createMockSharedPreference() {
// Mocking reading the SharedPreferences as if mMockSharedPreferences was previously written
// correctly.
when(mMockSharedPreferences.getString(Matchers.eq("name"), anyString()))
.thenReturn(TEST_NAME);
when(mMockSharedPreferences.getString(Matchers.eq("gender"), anyString()))
.thenReturn("M");
// Mocking a successful commit.
when(mMockEditor.commit()).thenReturn(true);
// Return the MockEditor when requesting it.
when(mMockSharedPreferences.edit()).thenReturn(mMockEditor);
return new SharedPreferencesHelper(mMockSharedPreferences, context);
}
}

运行测试失败,因为我使用了 getString在我的 SharedPreferencesHelper类(class)。如果我对键进行硬编码,我将不会收到错误,即:

public String fetchName() {
// Start a SharedPreferences transaction.
return mSharedPreferences.getString("name","");
}

不应该在代码中硬编码字符串,那么我该如何解决这个难题?

最佳答案

您可以通过不使用 Context 来获取字符串资源,而是使用 Resources 类来解决这个问题。 Resources 具有相同的 getString 方法,但它不是最终的。

https://developer.android.com/reference/android/content/res/Resources.html#getString(int)

或者,您可以试用 Robolectric,它可以解决这个问题,因为它们实现了上下文。

http://robolectric.org/

关于android - Mockito:如何将 getString 与 mockito 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38296278/

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