如何在Java8中测试需要用户在lambda函数中输入的代码?

如何在Java8中测试需要用户在lambda函数中输入的代码?,java,java-8,Java,Java 8,lambda很棒,我喜欢它们,但是我正在使用下面的代码,这段代码让我很难过,它使代码无法进行单元测试。代码请求一个UI对象,并使用该对象处理一些用户输入,然后再次运行自己的代码,该代码请求更多用户输入: (请记住,实际的代码并不是真正要求确认,所以它不是多余的,它实际上是要求将输入传递给几个函数调用中的一个选项,我只是简化了它,所以我不必在这里提供整个代码) 。您将如何处理所有这些用户输入的单元测试?在lambda中处理用户输入的替代方法是什么 GreenPlayerCard.java: pu

lambda很棒,我喜欢它们,但是我正在使用下面的代码,这段代码让我很难过,它使代码无法进行单元测试。代码请求一个UI对象,并使用该对象处理一些用户输入,然后再次运行自己的代码,该代码请求更多用户输入: (请记住,实际的代码并不是真正要求确认,所以它不是多余的,它实际上是要求将输入传递给几个函数调用中的一个选项,我只是简化了它,所以我不必在这里提供整个代码)

。您将如何处理所有这些用户输入的单元测试?在lambda中处理用户输入的替代方法是什么


GreenPlayerCard.java

public void cardOne((player, game) -> {
            TextUserInterface UI = TextUserInterface.getUI();

            Set<GreenPlayerCard> playerCards = player.getPlayerCards();

            discardCard = UI.getCardChoice(playerCards,"Choose a card to discard: ");

            Scanner scanner = new Scanner(System.in);
            String optionChoice = null;
            System.out.println("\t1- to Confirm Discard Card, enter 1");
            System.out.println("\t2- Do nothing, enter 2");
            System.out.print("Choice: ");
            optionChoice = scanner.nextLine();
        
            switch (optionChoice){
            case "1":
            {
                game.discardCard(discardCard, player);
                break;
            }           
            case "2":
                break;
                
            default: System.out.println("\tPlease enter your choice:");
            }
                break;
            }
})

这是一个与lambda表达式无关的问题。这是关于软件设计的。在您的代码中,一段实现程序逻辑的代码(恰好是一个lambda表达式)中有一个硬连线创建的
新扫描器(System.In)

这方面的问题与代码是lambda表达式这一事实无关,解决方案也不依赖于它。您必须从周围环境中提供
扫描仪
。通常,您必须抽象用户界面以使测试成为可能。如果您有一个
接口
,可以通过实际询问用户或从testcase中提供预定义值来实现,那么您可以测试在该
接口
的实例上工作的任何代码

对于
扫描器
来说,它更容易一些,因为它已经是一种抽象。您可以简单地创建一个对预定义输入进行操作的
扫描仪
实例,例如通过
StringReader
来启用对使用
扫描仪
的代码的测试。唯一的要求是,使用
扫描仪的代码不会以硬连线的方式创建自己的
扫描仪
实例,而是使用周围上下文提供的实例

在此,您可以考虑将代码放入命名方法中,因为它对于lambda表达式来说还是相当大的。也许这就是您已经尝试过的问题的无效代码片段:

public void cardOne(Scanner scanner, PlayerType player, GameType game) {
    TextUserInterface UI = TextUserInterface.getUI();
    Set<GreenPlayerCard> playerCards = player.getPlayerCards();
    discardCard = UI.getCardChoice(playerCards,"Choose a card to discard: ");

    String optionChoice = null;
    System.out.println("\t1- to Confirm Discard Card, enter 1");
    System.out.println("\t2- Do nothing, enter 2");
    System.out.print("Choice: ");
    input: for(;;) {
        optionChoice = scanner.nextLine();
        switch (optionChoice) {
        case "1":
            game.discardCard(discardCard, player);
            break input;
        case "2": break input;
        default: System.out.println("\tPlease enter your choice:");
        }
    }
}

但您可以考虑在应用程序的开头调用<代码>新的扫描器(System .in)并保持一个实例。


实际的lambda表达式遵循thump规则,即lambda表达式应该足够短,以至于“太简单而不能失败”,因此不需要自己的测试用例。每当lambda表达式变得如此复杂以至于你对此有疑问时,你应该考虑将代码移动到一个命名的、可测试的方法。

这是一个与lambda表达式无关的问题。这是关于软件设计的。在您的代码中,一段实现程序逻辑的代码(恰好是一个lambda表达式)中有一个硬连线创建的
新扫描器(System.In)

这方面的问题与代码是lambda表达式这一事实无关,解决方案也不依赖于它。您必须从周围环境中提供
扫描仪
。通常,您必须抽象用户界面以使测试成为可能。如果您有一个
接口
,可以通过实际询问用户或从testcase中提供预定义值来实现,那么您可以测试在该
接口
的实例上工作的任何代码

对于
扫描器
来说,它更容易一些,因为它已经是一种抽象。您可以简单地创建一个对预定义输入进行操作的
扫描仪
实例,例如通过
StringReader
来启用对使用
扫描仪
的代码的测试。唯一的要求是,使用
扫描仪的代码不会以硬连线的方式创建自己的
扫描仪
实例,而是使用周围上下文提供的实例

在此,您可以考虑将代码放入命名方法中,因为它对于lambda表达式来说还是相当大的。也许这就是您已经尝试过的问题的无效代码片段:

public void cardOne(Scanner scanner, PlayerType player, GameType game) {
    TextUserInterface UI = TextUserInterface.getUI();
    Set<GreenPlayerCard> playerCards = player.getPlayerCards();
    discardCard = UI.getCardChoice(playerCards,"Choose a card to discard: ");

    String optionChoice = null;
    System.out.println("\t1- to Confirm Discard Card, enter 1");
    System.out.println("\t2- Do nothing, enter 2");
    System.out.print("Choice: ");
    input: for(;;) {
        optionChoice = scanner.nextLine();
        switch (optionChoice) {
        case "1":
            game.discardCard(discardCard, player);
            break input;
        case "2": break input;
        default: System.out.println("\tPlease enter your choice:");
        }
    }
}

但您可以考虑在应用程序的开头调用<代码>新的扫描器(System .in)并保持一个实例。


实际的lambda表达式遵循thump规则,即lambda表达式应该足够短,以至于“太简单而不能失败”,因此不需要自己的测试用例。每当lambda表达式变得如此复杂以至于你对此有疑问时,你应该考虑将代码移动到一个命名的、可测试的方法。

这是一个与lambda表达式无关的问题。这是关于软件设计的。在您的代码中,一段实现程序逻辑的代码(恰好是一个lambda表达式)中有一个硬连线创建的
新扫描器(System.In)

这方面的问题与代码是lambda表达式这一事实无关,解决方案也不依赖于它。您必须从周围环境中提供
扫描仪
。通常,您必须抽象用户界面以使测试成为可能。如果您有一个
接口
,可以通过实际询问用户或从testcase中提供预定义值来实现,那么您可以测试在该
接口
的实例上工作的任何代码

对于
扫描器
来说,它更容易一些,因为它已经是一种抽象。您可以简单地创建一个对预定义输入进行操作的
扫描仪
实例,例如通过
StringReader
来启用对使用
扫描仪
的代码的测试。唯一的要求是,使用
扫描器的代码不会在hardw中创建自己的
扫描器
实例
(player, game) -> handleCardOne(new Scanner(System.in), player, game)