我正在测试我的Signup类的一个函数,但是每次运行它时,NullPointerException都会在它输入的第一个if语句中发生:
pass.show()
我怀疑它与没有使用模拟器测试应用程序有关。在测试时如何防止创建Toast的错误?
注册类中的功能:
public boolean checkInput(String username, String email, String password, String confirmpassword) {
if (!email.contains("@") || !email.contains(".com")) {
Toast pass = Toast.makeText(Signup.this, "Email must be valid!", Toast.LENGTH_SHORT);
pass.show();
return false;
}
if (!password.equals(confirmpassword)) {
Toast pass = Toast.makeText(Signup.this, "Passwords don't match!", Toast.LENGTH_SHORT);
pass.show();
return false;
}
if (!(password.length() >= 6)) {
Toast pass = Toast.makeText(Signup.this, "Password must be at least 6 characters", Toast.LENGTH_SHORT);
pass.show();
return false;
}
else {
return true;
}
}
测试方法:
@Test
public void testInvalidEmail() {
String testUser = "testUser";
String testEmail = "testEmail.com"; //invalid
String testPass = "testPass";
String testConfirmPass = "testPass";
assertFalse(signupClass.checkInput(testUser,testEmail,testPass,testConfirmPass));
}
你需要将Toast
与你的函数分离。为此,请按照以下步骤操作,我将使用您显示的示例并根据您的需要完全实现它们。希望这能回答您的询问,并且您能够完成。
首先创建一个打印界面(烘烤)
interface Printer {
void print(String message);
}
然后让你的Signup
类实现Printer
将Toast
与你的函数分离。我相信你的Signup
是一个Activity
。
public class Signup extends AppCompatActivity implements Printer {
// ... other codes ...
@Override
public void print(String message) {
Toast pass = Toast.makeText(Signup.this, message, Toast.LENGTH_SHORT);
pass.show();
}
}
然后,现在,删除你的Toast
函数中的checkInput
,并通过发送到函数的printer
执行打印
public boolean checkInput(String username, String email, String password, String confirmpassword, Printer printer) {
if (!email.contains("@") || !email.contains(".com")) {
printer.print("Email must be valid!");
return false;
}
if (!password.equals(confirmpassword)) {
printer.print("Passwords don't match!");
return false;
}
if (!(password.length() >= 6)) {
printer.print("Password must be at least 6 characters");
return false;
}
else {
return true;
}
}
注意:从你的类中调用checkInput
的函数需要发送Printer
,如果它在this
类中,则实际上是Signup
,例如
checkInput(testUser, testEmail, testPass, testConfirmPass, this)l;
现在在你的测试中,只需实现Mock Printer
,例如
@Test
public void testInvalidEmail(MainActivity mainActivity) {
String testUser = "testUser";
String testEmail = "testEmail.com"; //invalid
String testPass = "testPass";
String testConfirmPass = "testPass";
assertFalse(signUp.checkInput(testUser, testEmail, testPass, testConfirmPass, new Printer() {
@Override
public void print(String message) {
System.out.println(message);
}
}));
}
有了这个,您可以根据自己的愿望完成测试,同时您的应用程序仍可通过Toast
打印
如果您想要做的是UnitTesting,那么您需要为Android内容(如Toast)解耦代码。
一种方法是创建一个界面来显示Toast(或处理任何Android相关组件),以便您可以模拟它。
例如:
public interface AndroidInteraction (){
void showToast(Context context, String text, int length);
}
并在您的活动中实现该界面:
public class SignUpActivity extends AppCompatActivity implements AndroidInteraction{
.......
......
@Override
void showToast(Context context, String text, int length){
Toast pass = Toast.makeText(context, text, length);
pass.show();
}
最后你的Signup类应该知道那个接口,所以你可以传递它抛出它的构造函数:
AndroidInteraction androidInteraction;
public Signup (AndroidInteraction androidInteraction){
this.androidInteraction = androidInteraction;
}
所以你的方法现在看起来像(只有一个if子句来展示如何使用它,而不是整个方法):
if (!password.equals(confirmpassword)) {
androidInteraction.showToast(Signup.this, "Passwords don't match!", Toast.LENGTH_SHORT);
return false;
}
您需要在测试中模拟该接口并将其传递给类构造函数
而不是在变量'pass'上传递Toast,只需直接输入'Toast'并点击第二个建议。我也会删除你的回复。
这是我在你的代码中看到的问题:
Toast pass = Toast.makeText(.....);
如果你想把它放在变量上,那就这样做吧
Toast pass = new Toast(getContext());
pass.makeText (.....).show();
要么
pass.makeText(....);
pass.show();
所以我的建议是选择并试试这个:
public boolean checkInput(String username, String email, String password, String confirmpassword) {
if (!email.contains("@") || !email.contains(".com")) {
Toast.makeText(Signup.this, "Email must be valid!", Toast.LENGTH_SHORT).show();
}
if (!password.equals(confirmpassword)) {
Toast.makeText(Signup.this, "Passwords don't match!", Toast.LENGTH_SHORT).show();
}
if (!(password.length() >= 6)) {
Toast pass = Toast.makeText(Signup.this, "Password must be at least 6 characters", Toast.LENGTH_SHORT).show();
}
}