【问题标题】:How to Mock java.util.Scanner for a FileInput如何为 FileInput 模拟 java.util.Scanner
【发布时间】:2021-08-21 00:18:47
【问题描述】:

我在模拟来自在 CommandLineRunner 中运行的 STDIN 方式文件的输入时遇到问题。我已经尝试了多种方法,但是每当我运行测试时,应用程序都会要求我在命令行中插入文件。

我的命令行类:

@Slf4j
public class CommandLineAppStartupRunner implements CommandLineRunner {
    
    @Autowired
    private AutorizadorService service;

    @Override
    public void run(String...args) throws Exception {
        Scanner scan = new Scanner(System.in);
        log.info("provide file path:");
        service.init(scan.nextLine());
        scan.close();

    }
} ```

MyCommandLineTest class 1 try:

``` @SpringBootTest
public class CommandLineRunnerIntegrationTest {

    @Autowired
    private CommandLineRunner clr;

    @Test
    public void shouldRunCommandLineIntegrationTest1() throws Exception {
        File file = new File("D:/j.json");
        System.setIn(new FileInputStream(file));
        this.clr.run();
    }


    @Test
    public void shouldRunCommandLineIntegrationTest2() throws Exception {
        Scanner mockScanner = mock(Scanner.class);
        when(mockScanner.nextLine()).thenReturn("D:/j.json");
        mockScanner.nextLine();
        verify(mockScanner).nextLine();
    }

    @Test
    public void shouldRunCommandLineIntegrationTest3() throws Exception {
        InputStream in = new ByteArrayInputStream("D:/j.json".getBytes());
        System.setIn(in);
    }

} 

运行这些测试中的任何一个,我都会在命令行中看到这一点,并且只有在我手动输入输入时才能通过

2021-08-21 15:56:36.327  INFO 14772 --- [           main] b.c.a.r.CommandLineAppStartupRunner      : provide file path:

【问题讨论】:

  • 您的第一个测试运行您正在测试的代码您将System.in 重定向到您的文件之前。您的第二个测试不运行您的代码,而您的第三个测试只是重定向输入。您不提供模拟 AutorizadorService。请说明您预计会发生什么以及实际发生了什么。
  • 嗨,伙计,我编辑了我的帖子,并更新了描述。我正在寻找一种在运行 CommandLineRunner 时不需要在单元测试中手动输入文件路径的方法。

标签: java spring spring-boot mocking mockito


【解决方案1】:

如果您在 run 方法的开头设置断点,您会看到运行 @SpringBootTest 实际上会运行应用程序,即它会在找到的任何运行器上调用 run 方法。

您应该使用非 springboot 测试来测试该类:

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {CommandLineAppStartupRunner.class})
public class CommandLineRunnerIntegrationTest {

    @Autowired
    private CommandLineRunner clr;

    @Test
    public void shouldRunCommandLineIntegrationTest1() throws Exception {
        System.setIn(getClass().getResourceAsStream("/test.json"));
        this.clr.run();
    }
}

您的课程略微简化:

@Component
public class CommandLineAppStartupRunner implements CommandLineRunner {

    @Override
    public void run(String...args) throws Exception {
        Scanner scan = new Scanner(System.in);
        if (!scan.nextLine().equals("{ \"foo\":  \"bar\"}")) {
            throw new RuntimeException();
        }
        scan.close();
    }
}

您需要在测试类的@ContextConfiguration 中添加所需的任何其他配置。

【讨论】:

  • 感谢它非常有帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-02-02
  • 1970-01-01
  • 1970-01-01
  • 2011-06-26
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
相关资源
最近更新 更多