在Java Project中使用Mockito和JUnit进行测试时的问题

vkc1a9a2  于 12个月前  发布在  Java
关注(0)|答案(1)|浏览(170)

我在使用mockito和JUnit进行测试时遇到了一些问题,我想测试一个从用户输入中获取数据的方法。当我使用String id = "E833462"时,test函数可以正常工作,但是当我用generate函数替换它时,registerAccountTest()将在when(mockScanner.nextLine()).thenReturn(id, name, bd, role, sex, password);行被阻塞,我不知道为什么。虽然两种方法都是带ID的String。我测试了我的generate函数,而且它仍然可以创建一个随机的唯一ID。有人可以帮助我解决这个问题吗?谢谢你阅读我的问题,并试图找出它来帮助我。
这是我的测试方法

@Test
    void registerAccountTest() {
        Employee em = employees.searchById("E160052");

//        String id = "E833462";
        String id = Inputter.generateUniqueId("E", 6, employees);
        String name = "Test";
        String role = "MA";
        String sex = "Male";
        String bd = "08/03/2000";
        String password = "123456";

        String combinedUserInput =
                id + System.lineSeparator() + name + System.lineSeparator() + role + System.lineSeparator() + sex + System.lineSeparator() + bd + System.lineSeparator() + password;
        System.out.println(combinedUserInput);
        InputStream inputStream = new ByteArrayInputStream(combinedUserInput.getBytes());
        System.setIn(inputStream);

        Scanner mockScanner = spy(Inputter.scanner);
        System.out.println("Before when statement");
        when(mockScanner.nextLine()).thenReturn(id, name, bd, role, sex, password);
        System.out.println("After when statement");

        Executor.registerAccount(employees, em);

        Employee emTest = employees.searchById(id);
        assertNotEquals(null, emTest);
        assertEquals(name, emTest.getName());
        assertEquals(bd, emTest.getBirthdate().format(Inputter.formatterHalf));
        assertEquals(role, emTest.getRole());
        assertEquals(sex, emTest.getSex());

        employees.deleteOne(emTest);
    }

字符串
下面是我在Inputter类中的generate Id函数

public class Inputter {
    public static Scanner scanner = new Scanner(System.in);
    public static String generateUniqueId(String prefix, int len, ObjectList ol) {
        String id;

        do {
            int num = (int) random.nextDouble(Math.pow(10, len));
            id = prefix + String.format("%03d", num);
        } while (!Objects.isNull(ol.searchById(id)));

        return id.trim();
    }
}

bkhjykvo

bkhjykvo1#

spy调用不会改变Scanner对象,它创建了一个 Package 器。该 Package 器只存在于测试中。您需要替换类Inputter中的Scanner。在@BeforeEach中最容易做到这一点,因此您可以在@AfterEach中恢复它。

private Scanner originalScanner;
private Scanner mockScanner;

@BeforeEach
void mockScanner() {
    originalScanner = Inputter.scanner;
    mockScanner = spy(originalScanner);
    Inputter.scanner = mockScanner;
}

@AfterEach
void resetScanner() {
    Input.scanner = originalScanner;
}

@Test
void registerAccountTest() {
   ...
    System.setIn(inputStream);

    System.out.println("Before when statement");
    when(mockScanner.nextLine()).thenReturn(id, name, bd, role, sex, password);
    System.out.println("After when statement");
    ...
}

字符串
作为替代,您可以使用JUnit Pioneer。它允许您轻松替换System.in的结果,而无需任何手动设置。它还允许您读取写入System.outSystem.err的内容。

相关问题