我正在尝试弄清楚如何编写单元测试,但我卡在了一点:
假设我们有两个测试(模拟了 View 和服务):
@Test
public void shouldStartMainActivityWhenUsernameAndPassowordAreCorrect() throws Exception{
when(view.getUsername()).thenReturn("james");
when(view.getPassword()).thenReturn("bond"); //bond
when(serivce.login("james", "bnd")).thenReturn(true); //bnd gives error
presenter.onLoginClicked();
verify(view).startMainActivity();
}
@Test
public void shouldShowErrorMessangeWhenUsernameAndPasswordAreIncorrect() throws Exception{
when(view.getUsername()).thenReturn("james");
when(view.getPassword()).thenReturn("bond"); // bond
when(serivce.login("james", "bnd")).thenReturn(false); // bnd gives no error
presenter.onLoginClicked();
verify(view).showCredentialsError();
}
这是我的演示者方法:
public void onLoginClicked() {
String username = view.getUsername();
if (username.isEmpty()){
view.showUsernameError(R.string.username_error);
return;
}
String password = view.getPassword();
if (password.isEmpty()){
view.showPasswordError(R.string.password_error);
}
boolean loginSucceeded = service.login(username, password);
if (loginSucceeded){
view.startMainActivity();
}else{
view.showCredentialsError();
}
}
如何将“bnd”硬编码值与来自另一种方法的“bond”硬编码值进行比较?
例如:
when(view.getPassword()).thenReturn("bond"); //bond
when(serivce.login("james", "bnd")).thenReturn(true); //bnd
这给了我一个错误,同时将其更改为
when(view.getPassword()).thenReturn("bond"); //bond
when(serivce.login("james", "bond")).thenReturn(true); //bond
没有报错。
最佳答案
当您的服务返回一个 boolean 值表示登录是否成功时,您已经模拟了这两种情况。
您有以下模拟:
模拟
view.getUsername()
返回james
。每当从单元测试中对测试类调用此方法时,它都会返回此值。模拟
view.getPassword()
返回bond
。每当从单元测试中对测试类调用此方法时,它都会返回此值。serivce.login()
的模拟,它接受 2 个参数,即{"username","password"}
并返回登录状态,即true
或false
。每当使用相同的参数集从单元测试对测试类调用此方法时,它将返回这些值。
在第一个测试用例中,您从用户名 james
和密码:bnd
的 mock 中返回 false
,在第二个测试中,您为同一组参数返回 true
。
when(serivce.login("james", "bnd")).thenReturn(true); //bnd gives error
在这里,您为 {"james", "bnd"}
返回 true
。
when(serivce.login("james", "bnd")).thenReturn(false); // bnd gives no error
在这里,您为 {"james", "bnd"}
返回了 false
。
现在,在这两种情况下,这个模拟都没有被执行。这是因为演示者类中的 username
和 password
总是采用前 2 个模拟的值,即 view.getUsername()
和 查看.getPassword()
。这些模拟在两个测试用例中分别返回 james
和 bonds
。
从逻辑上讲,当且仅当参数是 {"james","bonds"} 时,您应该从测试用例中返回
而不是其他任何东西。然后将使用其他 2 个模拟返回的参数对其进行验证,并根据它们是否完全匹配,将执行第三个模拟并返回 boolean 值。true
或 false
积极的情景:
when(view.getUsername()).thenReturn("james");
when(view.getPassword()).thenReturn("bond");
when(serivce.login("james", "bond")).thenReturn(true); /* Corrected */
负面情景:
when(view.getUsername()).thenReturn("james");
when(view.getPassword()).thenReturn("bond");
when(serivce.login("james", "bond")).thenReturn(false); /* Corrected */
关于java - 为什么测试中的某些硬编码值会影响其他值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35238242/