android - 单元测试时来自 Toast 的 NullPointerException

标签 android junit android-toast

我正在测试我的 Signup 类的一个函数,但是每次我运行它时,在它输入的第一个 if 语句中会出现 NullPointerException:

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 与您的函数分离。为此,请按照以下步骤操作,我将在其中使用您显示的示例并完全根据您的需要实现它们。希望这能回答您的问题,并且您能够跟进。

首先创建一个用于打印(toasting)的接口(interface)

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();
    }
}

然后现在,在你的checkInput函数中删除你的Toast,并通过发送给函数的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 中发送,如果它在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

打印

关于android - 单元测试时来自 Toast 的 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52266797/

相关文章:

java - Android AccountManager.getUserData() 返回 null

java - Junit测试期望值

java - 如何对调用 void 方法的方法进行单元测试?

java - Toast 和 Progress 对话框边缘被切断

java - Android 自定义 toast 消息不能在单独的类中工作

java - Android 数据报套接字抛出 "NetworkOnMainThreadException"而不是 "SocketException"

Android:AlertDialog 中的按钮

android - Android Toast 可以比 Toast.LENGTH_LONG 长吗?

android - 无法在 XML .Android 工作室中更改按钮的背景颜色

unit-testing - 如何使用 Jersey(测试框架)将数据源依赖项注入(inject) RESTful Web 服务?