【发布时间】:2019-12-06 12:46:13
【问题描述】:
我得到通缉但未被调用。 checkFingerPrintWhenTouchIdEnabled() 方法在 verify(fingerPrintHelper, times(1)).initializeFingerPrint(any()); 行与此模拟错误的交互为零
.
甚至我也嘲笑过这个对象,并且在调试 initializeFingerPrint(..) 函数时会被调用。
下面是我要测试的功能,
@RequiresApi(Build.VERSION_CODES.M)
public void checkFingerPrint() {
if (fingerPrintHelper.isDeviceReadyForFingerPrint()) {
boolean isFingerPrintEnable = sharedPreference.getBoolean(SpKeys.KEY_FINGER_PRINT, false);
if (isFingerPrintEnable) {
fingerPrintHelper.initializeFingerPrint(this);
}
} else {
sharedPreference.putBoolean(SpKeys.KEY_FINGER_PRINT, false).commit();
}
}
LoginActvity.java
public class LoginActivity extends AppCompatActivity {
public FingerPrintHelper fingerPrintHelper;
ActivityLoginBinding binding;
private LoginViewModel loginViewModel;
private SharedPreferenceManager sharedPreferenceManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
sharedPreferenceManager = new SharedPreferenceManager(getApplicationContext(), SpKeys.MY_SP);
fingerPrintHelper = new FingerPrintHelper(this);
binding = DataBindingUtil.setContentView(this, R.layout.activity_login);
loginViewModel = ViewModelProviders.of(this).get(LoginViewModel.class);
binding.setViewModel(loginViewModel);
binding.setLifecycleOwner(this);
checkFingerPrint();
}
@RequiresApi(Build.VERSION_CODES.M)
public void checkFingerPrint() {
if (fingerPrintHelper.isDeviceReadyForFingerPrint()) {
boolean isFingerPrintEnable = sharedPreferenceManager.getBoolean(SpKeys.KEY_FINGER_PRINT, false);
if (isFingerPrintEnable) {
fingerPrintHelper.initializeFingerPrint(this);
}
} else {
sharedPreferenceManager.setBoolean(SpKeys.KEY_FINGER_PRINT, false);
}
}
}
我正在为此函数编写正负测试用例,而 checkFingerPrintWhenTouchIdDisabled() 测试工作正常,但 checkFingerPrintWhenTouchIdEnabled() 测试函数出现错误
请参考下面的测试类
LoginActivityTest.java
public class LoginActivityTest {
LoginActivity loginActivity;
@Mock
FingerPrintHelper fingerPrintHelper;
@Rule
public ActivityTestRule<LoginActivity> loginActivityRule = new ActivityTestRule<>(
LoginActivity.class);
Context context;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
loginActivity = loginActivityRule.getActivity();
context = getInstrumentation().getTargetContext();
}
@Test
public void checkFingerPrintWhenTouchIdDisabled() {
SharedPreferences sharedPreferences = context.getSharedPreferences(SpKeys.MY_SP, Context.MODE_PRIVATE);
when(fingerPrintHelper.isDeviceReadyForFingerPrint()).thenReturn(false);
loginActivity.checkFingerPrint();
Assert.assertFalse(sharedPreferences.getBoolean(SpKeys.KEY_FINGER_PRINT, false));
verify(fingerPrintHelper, never()).initializeFingerPrint(any());
}
@Test
public void checkFingerPrintWhenTouchIdEnabled() {
SharedPreferences sharedPreferences = context.getSharedPreferences(SpKeys.MY_SP, Context.MODE_PRIVATE);
SharedPreferences.Editor preferencesEditor = sharedPreferences.edit();
when(fingerPrintHelper.isDeviceReadyForFingerPrint()).thenReturn(true);
preferencesEditor.putBoolean(SpKeys.KEY_FINGER_PRINT, true).commit();
loginActivity.checkFingerPrint();
/* Below verification for `initializeFingerPrint()` is throwing error as,
Actually, there were zero interactions with this mock. error,
Even I have mock the object & while debugging the method is getting invoked also.
If I debug my code it calls this function but in test cases it shows above error
*/
verify(fingerPrintHelper, times(1)).initializeFingerPrint(any());
}
}
那为什么我的测试用例会出现零交互错误?可能是什么问题,感谢任何帮助。
提前致谢。
【问题讨论】:
-
@second 很抱歉给您带来不便。我已经更新了文件。
-
该异常似乎与您在
android environment中生成某些内容的方式有关。可能与mockito本身无关,但我也不确定您将如何在单元测试环境中处理这些东西。 -- 设置中的分配不应该是必要的,一个简单的基于规则的带有注释的测试没有它也可以正常工作。 -
如果我之前理解正确的话,那么最好的选择可能是遵循
Maciej Kowalski的建议并手动设置你的模拟。 -
@second,
set up your mocks manually instead.你能详细说明这个术语吗?如何通过手动设置 mokes 来模拟 LoginActivity?如何使用 setter 注入模拟?我应该为 LoginActivity 这样做吗? -
我添加了一个示例作为答案(因为 cmets 中的代码无法正确格式化)。将其视为
Maciej Kowalski答案的扩展。
标签: java android mockito android-testing testcase