Hello! Can you please tell me if I made the Junit tests correctly?

import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.*; public class Calculator extends JFrame { private String[] operation = {"+"}; private double first_value = 0; private double second_value = 0; JFrame jframe = new JFrame("Калькулятор"); //форма //Создание панели для кнопок грид лояут(Менеджер расположения) JPanel panel = new JPanel(new GridLayout(4, 4, 5, 5)); JPanel batton_equally = new JPanel(new BorderLayout(1, 1)); //Создаем панель для текста JPanel panel_text = new JPanel(new BorderLayout()); //Создаем текстовое поле JTextField jtextfield = new JTextField(20); //Создаем кнопки JButton bt1 = new JButton("7"); JButton bt2 = new JButton("8"); JButton bt3 = new JButton("9"); JButton btС = new JButton("С"); JButton bt4 = new JButton("4"); JButton bt5 = new JButton("5"); JButton bt6 = new JButton("6"); JButton bt_div = new JButton("/"); JButton bt7 = new JButton("1"); JButton bt8 = new JButton("2"); JButton bt9 = new JButton("3"); JButton bt_mult = new JButton("*"); JButton bt10 = new JButton("."); JButton bt11 = new JButton("0"); JButton bt_res = new JButton("="); JButton bt13 = new JButton("+"); JButton bt14 = new JButton("-"); public Calculator() { jframe.setSize(300, 300); //Обработка щелчка на системной кнопке закрытия окна jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jframe.setLocationRelativeTo(null); //? jframe.setLayout(new BorderLayout()); //Выравнивание текста в поле по правому краю jtextfield.setHorizontalAlignment(JTextField.RIGHT); //Установка шрифта и размер текстового поля jtextfield.setFont(new Font("Times New Roman", Font.PLAIN, 20)); //Задаем вид и размер шрифта кнопок btС.setFont(new Font("Tahoma", Font.BOLD, 15)); bt_div.setFont(new Font("Tahoma", Font.BOLD, 15)); bt_mult.setFont(new Font("Tahoma", Font.BOLD, 15)); bt10.setFont(new Font("Tahoma", Font.BOLD, 15)); bt_res.setFont(new Font("Tahoma", Font.BOLD, 20)); bt13.setFont(new Font("Tahoma", Font.BOLD, 15)); bt14.setFont(new Font("Tahoma", Font.BOLD, 20)); //Добавление кнопки на панель panel.add(bt1); panel.add(bt2); panel.add(bt3); panel.add(btС); panel.add(bt4); panel.add(bt5); panel.add(bt6); panel.add(bt_div); panel.add(bt7); panel.add(bt8); panel.add(bt9); panel.add(bt_mult); panel.add(bt10); panel.add(bt11); panel.add(bt13); panel.add(bt14); batton_equally.add(bt_res); //цвет панели panel.setBackground(Color.CYAN); //Добавляем текстовое поле на панель panel_text.add(jtextfield, BorderLayout.NORTH); //Добавляем панель текста на форму jframe.add(panel_text, BorderLayout.NORTH); //Добавляем панель кнопок на форму jframe.add(panel, BorderLayout.CENTER); jframe.add(batton_equally, BorderLayout.SOUTH); //Видимость формы jframe.setVisible(true); //Обработчики события "Нажатие на кнопку" //ActionListener - слушатель bt1.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { jtextfield.setText(jtextfield.getText() + "7"); } }); bt2.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { jtextfield.setText(jtextfield.getText() + "8"); } }); bt3.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { jtextfield.setText(jtextfield.getText() + "9"); } }); bt4.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { jtextfield.setText(jtextfield.getText() + "4"); } }); bt5.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { jtextfield.setText(jtextfield.getText() + "5"); } }); bt6.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { jtextfield.setText(jtextfield.getText() + "6"); } }); bt7.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { jtextfield.setText(jtextfield.getText() + "1"); } }); bt8.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { jtextfield.setText(jtextfield.getText() + "2"); jtextfield.setEnabled(true); } }); bt9.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { jtextfield.setText(jtextfield.getText() + "3"); } }); //Запрещаем ввод точки более 1 раза //Анонимный обработчик нажатия actionPerformed(ActionEvent e) //Выводим на экран точку потом проверяем эту точу в регулярном выражении и если верно то выводим точку bt10.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { String newText = jtextfield.getText() + "."; if (validinput(newText)) { jtextfield.setText(newText); } } }); bt11.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { jtextfield.setText(jtextfield.getText() + "0"); } }); //При нажатии на "C" удаляем последнюю цифру btС.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { String temp = jtextfield.getText(); //обрабатываем исключение, чтобы не было возможности стереть пустое значение try { jtextfield.setText(temp.substring(0, temp.length() - 1)); } catch (Exception e1) { } } }); // Работаем с кнопками операции // Для каждого арифметического действия запомнить его, сохранить текущее число в переменной first_value и // сбрасывать число для ввода нового bt14.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { first_value = Double.valueOf(jtextfield.getText()); } catch (Exception e1) { } jtextfield.setText(""); operation[0] = "-"; } }); bt_div.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { first_value = Double.valueOf(jtextfield.getText()); } catch (Exception e1) { } jtextfield.setText(""); operation[0] = "/"; } }); bt_mult.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { first_value = Double.valueOf(jtextfield.getText()); } catch (Exception e1) { } jtextfield.setText(""); operation[0] = "*"; } }); bt13.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { first_value = Double.valueOf(jtextfield.getText()); } catch (Exception e1) { } jtextfield.setText(""); operation[0] = "+"; } }); //Обрабатываем при нажатии на равно, считаем второе значение с текстового поля bt_res.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { result(); } catch (DivisionByZero e1) { //e1.printStackTrace(); JOptionPane.showMessageDialog(Calculator.this, "Деление на ноль запрещено!", "Error", JOptionPane.ERROR_MESSAGE); jtextfield.setText(""); } catch (Exception e1) { } } }); //запрещает ввод всех букв и символов с клавиатуры, кроме цифр jtextfield.addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { super.keyPressed(e); Pattern p = Pattern.compile("^(([0-9]){0,}([\\.]){0,})+$"); Matcher m = p.matcher(jtextfield.getText()); if (!m.matches()) { jtextfield.setEnabled(false); } } }); }//закрытие конструктора // Метод проверяет строку на содержание точки private boolean validinput(String input) { Pattern p = Pattern.compile("^(\\d+)(\\.{0,1})?$"); return p.matcher(input).find(); } public static void main(String[] args) { new Calculator(); } //Проводит все вычисления для кнопки равно и перехватывает это исключение. Метод бросает исключение "Деление на ноль" void result() throws DivisionByZero { double second_value = Double.valueOf(jtextfield.getText()); if ("+".equals(operation[0])) { jtextfield.setText((first_value + second_value) + ""); } else if ("-".equals(operation[0])) { jtextfield.setText((first_value - second_value) + ""); } else if ("/".equals(operation[0])) { if (second_value == 0) { throw new DivisionByZero(); } jtextfield.setText((first_value / second_value) + ""); } else if ("*".equals(operation[0])) { jtextfield.setText((first_value * second_value) + ""); } } private class DivisionByZero extends Exception { } } //JUnit test public class CalculatorTest { @Test void result() { assertEquals(5, 2 + 3); assertEquals(6, 2 * 3); assertEquals(2, 5 - 3); assertEquals(2, 6 / 3); assertEquals(10.2, 6.2 + 4); assertEquals(-1, 7 - 8); } } 
  • one
    If you wanted to test how Java itself handles the calculations, then yes, that's right. But your calculator you have not tested per gram. - andreycha
  • but, if so, it does not work assertEquals (4, new Calculator (). result (2 + 2)); - Alex Lip

1 answer 1

The first. The test you wrote tests only how the JVM itself does the computation.

The second. The test should test your Calculator class. However, if you try to write such a test, you will fail. Why?

Third. Unit tests should test only the application logic and should not touch anything else, for example, UI, access to the database or web services.

What is the problem of class Calculator ? The fact that it is mixed with the logic of mathematical calculations and the logic of representation (UI). All the math you have is in the result() method. First you need to remove everything related to the UI from it and leave only the math. For example, somehow ( compilation errors are possible, I haven’t written on Java for a long time ):

 double result(double a, double b, string op) throws DivisionByZero { if ("+".equals(op)) { return a + b; } else if ("-".equals(op)) { return a - b; } else if ("/".equals(op)) { if (b == 0) { throw new DivisionByZero(); } return a / b; } else if ("*".equals(op)) { return a * b; } } 

Now, after making this method public (or rather, taking it to the Calculator class, and renaming the current class to, for example, CalculatorFrame ), you can write tests that look something like this:

 @Test void resultAddition() { Calculator calculator = new Calculator(); double res = calculator.result(2, 3, "+"); assertEquals(5, res); } @Test void resultMultiplication() { Calculator calculator = new Calculator(); double res = calculator.result(2, 3, "*"); assertEquals(6, res); } 

Some tips about tests:

  1. Do one test per one case (addition, subtraction, multiplication, division and division by zero).
  2. In each test, you can check several variants of the data (for example, with zero and negative numbers).