繁体   English   中英

如何为具有局部变量的方法编写 Junit 测试

[英]How to write Junit test for methods with local variables

我写了一个方法,要求用户按回车键继续并在一段时间后超时。 我在为此方法编写 Junit 测试时遇到困难,使用 Mockito。 下面是方法。

private static final ExecutorService l = Executors.newFixedThreadPool(1);

private static String getUserInputWithTimeout(int timeout) {
    Callable<String> k = () -> new Scanner(System.in).nextLine();
    LocalDateTime start = LocalDateTime.now();
    Future<String> g = l.submit(k);
    while (ChronoUnit.SECONDS.between(start, LocalDateTime.now()) < timeout) {
        if (g.isDone()) {
            try {
                String choice = g.get();
                return choice;
            } catch (InterruptedException | ExecutionException | IllegalArgumentException e) {
                logger.error("ERROR", e);
                g = l.submit(k);
            }
        }
    }
    logger.info("Timeout...");
    g.cancel(true);
    return null;
}

我尝试了 mocking Callable 和 Future 但由于这种方法是在本地创建它们,因此在 Test 中创建它们没有影响。

我尝试了几件事,但没有按预期工作,我可能做错了。

@Test
    public void testgetUserInputWithUserInput() throws Exception {
        
         Scanner scanner = new Scanner(System.in);
         Callable<String> callable = PowerMockito.mock(Callable.class);
        

         ExecutorService executorServiceMock = PowerMockito.mock(ExecutorService.class);
     
         Future<String> futureMock = PowerMockito.mock(Future.class);
         when(executorServiceMock.submit(any(Callable.class))).thenReturn(futureMock);


        assertEquals("", getUserInputWithTimeout(3));
    }

我想说你需要稍微改变你的方法,从方法中取出可调用的 object 并将其作为参数传递,这应该可以解决 mocking 的问题。

private static final ExecutorService l = Executors.newFixedThreadPool(1);

private static String getUserInputWithTimeout(int timeout, Callable<String> k) {
    LocalDateTime start = LocalDateTime.now();
    Future<String> g = l.submit(k);
    while (ChronoUnit.SECONDS.between(start, LocalDateTime.now()) < timeout) {
        if (g.isDone()) {
            try {
                String choice = g.get();
                return choice;
            } catch (InterruptedException | ExecutionException | IllegalArgumentException e) {
                logger.error("ERROR", e);
                g = l.submit(k);
            }
        }
    }
    logger.info("Timeout...");
    g.cancel(true);
    return null;
}

您的测试应如下所示:

@Test
public void testgetUserInputWithUserInput() throws Exception {
    
    String ENTER = " ";
    System.setIn(new ByteArrayInputStream(ENTER.getBytes()));

    Callable<String> callable = () -> new Scanner(System.in).nextLine();

    assertEquals(ENTER, getUserInputWithTimeout(5, callable));
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM