无限循环的单元测试



这是我的Java线程运行方法,我想为此方法编写单元测试。但是有了Infinte循环,我做不到。任何人都可以帮助我。

 public void run() {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String line = null;
        boolean oneTime = true;
        loadDescription();
        while (true) {
            try {
                if (oneTime) {
                    System.out.println("press enter to get the console...............");
                    oneTime = false;
                }
                line = in.readLine();
                if (line != null) {
                    processInput(line);
                }
            } catch (Exception e) {
                logger.error("Error occurred while processing console");
                logger.error(e.getMessage(), e);
            }
        }
    }

这是LoadDescription()方法

private void loadDescription() {
        BufferedReader in = null;
        StringBuffer stringBuffer = null;
        String str = null;
        try {
            stringBuffer = new StringBuffer();
            in = new BufferedReader(new FileReader(IConstants.MANUAL_FILE));
            str = in.readLine();
            while (str != null) {
                stringBuffer.append(str + "n");
                str = in.readLine();
            }
            dfixDescription = stringBuffer.toString();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);  //To change body of catch statement use File | Settings | File Templates.
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                logger.error(e.getMessage(), e);  //To change body of catch statement use File | Settings | File Templates.
            }
        }
    }

private void processInput(String line) {
        line = line.trim();
        logger.info("Admin Message received: " + line);
        if ("?".equalsIgnoreCase(line) || "".equals(line)) {
              printDescription();
        } else if (line.toUpperCase().startsWith(AdminCommands.RELOAD)) {
            loadDescription();
            printDescription();
        } else if (line.toUpperCase().startsWith(AdminCommands.EXIT)) {
            adminManager.stopDFIXRouter();
            logger.debug("Closing Application.....");
            logger.debug("Closed.");
            System.exit(0);
        } else if (line.toUpperCase().startsWith(AdminCommands.RESET_OUT_SEQUENCE)) {
            try {
                String sessionIdentifier = line.split(",")[1].trim();
                int seqNo = Integer.parseInt((line.split(",")[2]).trim());
                adminManager.resetOutSequence(sessionIdentifier, seqNo);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);  //To change body of catch statement use File | Settings | File Templates.
            }
        } else if (line.toUpperCase().startsWith(AdminCommands.RESET_IN_SEQUENCE)) {
            try {
                String sessionIdentifier = line.split(",")[1].trim();
                int seqNo = Integer.parseInt((line.split(",")[2]).trim());
                adminManager.resetInSequence(sessionIdentifier, seqNo);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);  //To change body of catch statement use File | Settings | File Templates.
            }
        } else if (line.toUpperCase().startsWith(AdminCommands.CONNECT)) {
            String sessionIdentifier = line.split(",")[1].trim();
            adminManager.connectSession(sessionIdentifier);
        } else if (line.toUpperCase().startsWith(AdminCommands.DISCONNECT)) {
            String sessionIdentifier = line.split(",")[1].trim();
            adminManager.disconnectSession(sessionIdentifier);
        } else if (line.toUpperCase().startsWith(AdminCommands.ACTIVATE)) {
            adminManager.startDFIXRouter();
        } else if (line.toUpperCase().startsWith(AdminCommands.PASSIVATE)) {
            adminManager.stopDFIXRouter();
        } else if (line.toUpperCase().startsWith(AdminCommands.RUN_EOD)) {
            try {
                String sessionIdentifier = line.split(",")[1].trim();
                adminManager.runEod(sessionIdentifier);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);  //To change body of catch statement use File | Settings | File Templates.
            }
        } else if (line.toUpperCase().startsWith(AdminCommands.SHOW_STATUS)) {
            adminManager.showStatus();
        } else {
            System.out.println("Usage: type ? for help");
        }
        System.out.print(">");
    }

这些是运行方法的相关方法。以下是我的测试方法

 @Test
    public void run_activate() throws Exception{
        String data = "activate";
        InputStream in = new ByteArrayInputStream(data.getBytes());
        System.setIn(in);
        PowerMockito.mockStatic(AdminManager.class);
        PowerMockito.when(AdminManager.getInstance()).thenReturn(adminManagerTest);
        Mockito.doNothing().when(adminManagerTest).startDFIXRouter();
        dfixrtrAdminTest.run();
        Mockito.verify(adminManagerTest, Mockito.times(1)).startDFIXRouter();
    }

这是什么问题。当我运行测试方法时,它将不会停止,也无法验证所需的方法如何处理。

您需要用功能替换无限循环内的代码。

您然后为该功能编写一个单元测试。

显然您无法测试循环是否真的是"无限"。

但是,您仍然可以退后一步,看看所有此方法所做的详细信息,例如:

  • 打开一个读者,它将从中读取
  • 拥有这种特殊条件可以确保"某事"仅发生一次

换句话说:通常,在单位测试中,您可以仔细考虑代码可以采取的不同路径(思考:"白盒测试")。可以告诉您有关击中角案件所需的测试用例。另一方面,您还应该查看方法的公共合同(黑匣子测试) - 您期望这种方法会做什么,而不了解其实施。这就是您如何考虑代码,以便提出合理的测试。

之后,您的示例是虚假的。这里不应该有一个无限的循环 - 在某些时候,所有行都将被读取,而read()除了null之外不会返回其他任何行。

[晚答案] @isharad @ghostcat的答案很好。我还面临此问题,解决该问题的最佳方法是将逻辑的执行与线程执行分开。Runnable类就像包装器,您可以在其中委派自己的方法执行。另外,它将帮助您简化测试。

您应该有这样的东西:

您的课:

public class YourClass {
    public void execute() {
        ...
    }
}

您的可运行:

public class YourClassTask implements Runnable {
    private YourClass yourClass;
    public YourClassTask(YourClass yourClass) {
        this.yourClass = yourClass;
    } 
    @Override
    public void run() {
        yourClass.execute();
    }
}

相关内容

  • 没有找到相关文章

最新更新