junit 如果方法有需要系统输入的开关,如何编写单元测试?

tvz2xvvm  于 2022-11-29  发布在  其他
关注(0)|答案(1)|浏览(137)

我有一个BillServiceImpl的方法,它要求在运行以下任何方法之前先添加您的选项。但是,我不知道如何编写此服务的测试。
我的服务是这样的:

@Override
public void addBill(Bill bill, Menu menu) {
    Scanner scanner = new Scanner(System.in);
    List<BillItems> billItemsList = bill.getBillItemsList();

    menu();
    System.out.print("Insert menu you want to be served: ");
    option = scanner.nextLine();
    try {
        switch (option){
            case "1":
                menuPrinter.printMenu(menu.getFoodMenu());
                foodMenuOption();
                System.out.print("Choose menu you want to eat: ");
                menuOption = scanner.nextLine();

                switch (menuOption) {
                    case "1" -> {
                        BreakfastMenu breakfastMenu = menu.getFoodMenu().getBreakfastMenu();
                        if(breakfastMenu == null){
                            throw new NullPointerException("Breakfast menu is blank !!!");
                        }
                        billItemsList = billItemServices.addMenuItemsToBill(billItemsList, breakfastMenu);
                        bill.setBillItemsList(billItemsList);
                    }
                    case "2" -> {
                        LunchMenu lunchMenu =  menu.getFoodMenu().getLunchMenu();
                        if(lunchMenu == null){
                            throw new NullPointerException("Lunch menu is blank !!!");
                        }
                        billItemsList = billItemServices.addMenuItemsToBill(billItemsList, lunchMenu);
                        bill.setBillItemsList(billItemsList);
                    }
                    case "3" -> {
                        DinnerMenu dinnerMenu = menu.getFoodMenu().getDinnerMenu();
                        if(dinnerMenu  == null){
                            throw new NullPointerException("Dinner menu is blank !!!");
                        }
                        billItemsList = billItemServices.addMenuItemsToBill(billItemsList, dinnerMenu);
                        bill.setBillItemsList(billItemsList);
                    }
                    default -> System.out.println("No option found !!!");
                }
                break;
            case "2":
                menuPrinter.printMenu(menu.getDrinkMenu());
                drinkMenuOption();
                System.out.print("Choose menu you want to drink: ");
                menuOption = scanner.nextLine();
                switch (menuOption) {
                    case "1" -> {
                        Alcohol alcohol = menu.getDrinkMenu().getAlcohol();
                        if(alcohol == null){
                            throw new NullPointerException("Alcohol menu is blank !!!");
                        }
                        billItemsList = billItemServices.addMenuItemsToBill(billItemsList, alcohol);
                        bill.setBillItemsList(billItemsList);
                    }
                    case "2" -> {
                        SoftDrinks softDrinks = menu.getDrinkMenu().getSoftDrinks();
                        if(softDrinks == null){
                            throw new NullPointerException("Soft drink menu is blank !!!");
                        }
                        billItemsList = billItemServices.addMenuItemsToBill(billItemsList, softDrinks);
                        bill.setBillItemsList(billItemsList);
                    }
                    default -> System.out.println("No option found !!!");
                }
                break;
            case "e":
                break;
            default:
                System.out.println("No option found !!!");
                break;
        }
    }catch (NullPointerException exception){
        System.out.println(exception.getMessage());
    }
}

我的考验是这样的:

@RunWith(MockitoJUnitRunner.class)
public class BillServicesTest {

private BillServices billServices;

@Before
public void init(){
    billServices = new BillServicesImpl();
}

@Test
public void whenAddNewMenuItemToBill_returnNewBill(){
    Bill bill = new Bill();
    Menu   menu =  new Menu();
    billServices.addBill(bill,menu);
    verify(billServices).addBill(bill,menu);
}

然而,当我运行测试时,它会无限地保持加载状态。可能是该方法需要扫描仪的信息来实现切换功能。
我应该如何写这个方法的测试呢?我是测试的初学者,谢谢你的支持。

8i9zcol2

8i9zcol21#

我用了最少的代码来演示输入中的模拟,因为你的实体是不可用的。还添加了Junit5的测试,但它应该与Junit4类似。
测试类别:

public class BillingService {

    public void addBill() {
        Scanner scanner = new Scanner(System.in);

        System.out.print("Insert menu you want to be served: ");
        var option = scanner.nextLine();
        var menuOption = scanner.nextLine();

        try {
            switch (option) {
                case "1":
                    System.out.print("Choose menu you want to eat: ");

                    switch (menuOption) {
                        case "1" -> System.out.println("1");
                        case "2" -> System.out.println("2");
                        case "3" -> System.out.println("3");
                        default -> System.out.println("No option found !!!");
                    }
                    break;
                case "2":
                    System.out.print("Choose menu you want to drink: ");
                    menuOption = scanner.nextLine();
                    switch (menuOption) {
                        case "1" -> System.out.println("1.2");
                        case "2" -> System.out.println("2.2");
                        default -> System.out.println("No option found !!!");
                    }
                    break;
                case "e":
                    System.out.println("e");
                    break;
                default:
                    System.out.println("No option found !!!");
                    break;
            }
        } catch (NullPointerException exception) {
            System.out.println(exception.getMessage());
        }
    }
}

您可以按如下方式设置输入:

@ExtendWith(MockitoExtension.class)
class BillingServiceTest {

    private BillingService billingService;

    private final InputStream systemIn = System.in;
    private final PrintStream systemOut = System.out;

    private ByteArrayInputStream testIn;
    private ByteArrayOutputStream testOut;

    @BeforeEach
    public void init() {
        billingService = new BillingService();

        testOut = new ByteArrayOutputStream();
        System.setOut(new PrintStream(testOut));
    }

    @AfterEach
    public void restoreSystemInputOutput() {
        System.setIn(systemIn);
        System.setOut(systemOut);
    }

    @Test
    public void whenAddNewMenuItemToBill_returnNewBill() {
        provideInput("3\n2");
        billingService.addBill();
    }

    private void provideInput(String data) {
        testIn = new ByteArrayInputStream(data.getBytes());
        System.setIn(testIn);
    }
}

在这里,我们设置option = 3和menuOption = 2。该代码是不言自明的,因为它只是设置System.in,答案基于https://stackoverflow.com/a/50721326/7155432

相关问题