如何使用 Junit 4 测试 java 输入和预期输出

问题描述 投票:0回答:1

如何测试Java输入/输出

你好,

我有以下问题:我有一个类,它处理用户交互(输入/输出),我需要为其编写 Junit4 测试。

我想测试的类看起来像这样:

package program;
// imports
public class UserInteraction {
    private Program program;

    private UserInteraction(){
        program = new Program();
    }

    // Menu display
    private void start() {
        while (!program.getProgramStarted) {
            String input = readInput();
            switch (input) {
            case "1":
                addUser();
                break;
            case "2":
                deleteUser();
                break;
            case "3":
                // ...
            default:
                System.err.println("Unknown option");
                break;
            }
        }
    }

    private void addUser() {
        // Output
        String username = readInput();
        program.addUser(username);
        System.out.println("User " + username + "added");
    }

    private void deleteUser() {
        // Output
        String username = readInput();
        program.deleteUser(username);
        System.out.println("User " + username + "deleted");
    }

    @SuppressWarnings("resource")
    private String readInput() {
        return (new Scanner(System.in)).nextLine();
    }

    public void main(String[] args) {
        UserInteraction ui = new UserInteraction();
        ui.start();
    }

}

程序类看起来像这样:

package program;
// imports
public class Program {
    // fields
    private User currentUser;
    private List<User> user = new ArrayList<User>();
    // constructor

    public void addUser(String name) throws Exception {
        if (user.size() >= 6) {
            throw new Exception();
        }
        int newID = user.size() + 1;
        user.add(new User(name, newID));
    }

    public String[] getALlUser() {
        int counter = 0;
        String[] userArray = new String[user.size()];

        for (User s : user) {
            userArray[counter++] = s.toString();
        }
        return userArray;
    }
}

现在,例如,我想测试以下输入是否被正确处理:

1
John
=> User John added

为此,我编写了一个 Junit 测试,如下所示:

package tests;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.PrintStream;

import org.junit.After;
import org.junit.Test;

import program.*;

public class UserInteractionTest {

    private final InputStream originalIn = System.in;
    private final PrintStream originalOut = System.out;
    private Program program;

    @After
    public void restoreStreams() {
        System.setIn(originalIn);
        System.setOut(originalOut);
    }

    @Test
    public void testCreateUser() throws Exception {
        String input = "1\nJohn\n";
        ByteArrayInputStream in = new ByteArrayInputStream(input.getBytes());
        System.setIn(in);
        ByteArrayOutputStream outContent = new ByteArrayOutputStream();
        System.setOut(new PrintStream(outContent)); // Leitet System.out um

        program = new Program();
        try {
            program.main(null);
        } finally {
            System.setIn(originalIn);
        }
        String expectedOutput = "User John added";
        assertTrue("Output not found", outContent.toString().contains(expectedOutput));
    }

}

输入(“1 ") 已完成,但之后没有插入任何输入,因此测试挂起。 有谁知道如何解决这个问题?或者,也许是测试/验证 Java 程序的输入/输出的更好方法?

提前致谢!

我尝试对输入流进行各种修改,例如使用

System.lineSeparator()
而不是
\n
,但问题仍然存在。

java unit-testing junit junit4
1个回答
0
投票

直接调用

main
方法并期望整个流程自行发生,本质上并不是单元测试。编写单元测试是为了以隔离的方式测试/验证最小的可执行代码(单元)。这意味着您单独测试方法中的每个流程,将其与外部行为分开。这种隔离通常使用测试替身 (mocks)

来完成

我建议您通过参考官方文档和其他可用资源来正确理解基础知识

© www.soinside.com 2019 - 2024. All rights reserved.