2015-06-23 4 views
0

Привет, я пытаюсь опробовать тестирование Junit, и я не могу найти способ протестировать другой класс без копирования, вставляя его части. Скажем, я хочу протестировать это:Junit - тестирование другого класса

import java.io.*; 

public class Calculator { 

public static void main(String[] args) { 
    String s1 = getInput("Enter a numeric value: "); 
    String s2 = getInput("Enter a numeric value: "); 
    String op = getInput("Enter 1=ADD, 2=Subtract, 3=Multiply, 4=Divide "); 

    int opInt = Integer.parseInt(op); 
    double result = 0; 

    switch (opInt) { 
    case 1: 
     result = addValues(s1, s2); 
     break; 
    case 2: 
     result = subtractValues(s1, s2); 
     break; 
    case 3: 
     result = multiplyValues(s1, s2); 
     break; 
    case 4: 
     result = divideValues(s1, s2); 
     break; 

    default: 
     System.out.println("You entered an incorrect value"); 
     return; 
    } 

    System.out.println("The answer is " + result); 

} 

private static double divideValues(String s1, String s2) { 
    double d1 = Double.parseDouble(s1); 
    double d2 = Double.parseDouble(s2); 
    double result = d1/d2; 
    return result; 
} 

private static double multiplyValues(String s1, String s2) { 
    double d1 = Double.parseDouble(s1); 
    double d2 = Double.parseDouble(s2); 
    double result = d1 * d2; 
    return result; 
} 

private static double subtractValues(String s1, String s2) { 
    double d1 = Double.parseDouble(s1); 
    double d2 = Double.parseDouble(s2); 
    double result = d1 - d2; 
    return result; 
} 

private static double addValues(String s1, String s2) { 
    double d1 = Double.parseDouble(s1); 
    double d2 = Double.parseDouble(s2); 
    double result = d1 + d2; 
    return result; 
} 

private static String getInput(String prompt) { 
    BufferedReader stdin = new BufferedReader(
      new InputStreamReader(System.in)); 

    System.out.print(prompt); 
    System.out.flush(); 

    try { 
     return stdin.readLine(); 
    } catch (Exception e) { 
     return "error: " + e.getMessage(); 
    } 
} 

Есть ли способ, который я могу настроить для проверки JUnit для проверки частей этого без копирования и вставки его для каждого теста или изменения оригинального класса. я что-то упустил или это что-то не может сделать?

Вот что я в данный момент:

import static org.junit.Assert.*; 

import java.io.BufferedReader; 
import java.io.InputStreamReader; 

import org.junit.Test; 


public class CalculatorTest { 

Calculator mycalculator = new Calculator(); 

@Test 
public void test1() { 
    mycalculator; 
    assertEquals(d1 + d2, 20); 
} 

} 
+0

Сделайте биты класса, к которому вы хотите получить доступ извне этого класса, видны - например. удалите 'private' из методов, которые вы хотите протестировать. –

+0

Можете ли вы опубликовать класс тестирования модуля, который вы сделали до сих пор, и указать, какой метод или методы вы хотите проверить? – vikingsteve

+1

В этом классе есть две вещи, которые затрудняют тестирование в JUnit: 1) Это чтение из stdin и запись в stdout. 2) Это все статично. Если вы сделаете его нестатичным, вы можете создать экземпляр класса с потоками ввода/вывода, которые вы контролируете, и сохранить их в переменных-членах. (Конечно, вы все равно можете иметь no-arg ctor, который создает его с помощью System.in и System.out). –

ответ

2

Дизайн вашего класса на самом деле не поддается автоматическому тестированию.

  • Единственные методы в классе являются частными статическими, а это означает, что они могут быть доступны только из других статических методов класса (хотя можно использовать Reflection, чтобы преодолеть это, если вы абсолютно необходимо иметь частные статические члены.)
  • Части класса требуют ввода/вмешательства пользователя, что затрудняет их автоматическое тестирование.
  • Ваш класс не является объектно-ориентированным. Он написан скорее как функциональная программа (например, C), с основным телом и глобальными функциями, а не как объект, предоставляющий функциональность.

попробовать что-то вроде этого, вместо:

import java.io.BufferedReader; 
import java.io.InputStreamReader; 

public class Calculator { 

    // TODO: Move enum to another file 
    public static enum OperatorType { 
     ADD, 
     SUBTRACT, 
     MULTIPLY, 
     DIVIDE 
    } 

    public double calculateResult(double operand1, double operand2, OperatorType operator) { 
     double result = 0;; 
     switch (operator) { 
      case ADD: 
       result = addValues(operand1, operand2); 
       break; 
      case DIVIDE: 
       result = subtractValues(operand1, operand2); 
       break; 
      case MULTIPLY: 
       result = multiplyValues(operand1, operand2); 
       break; 
      case SUBTRACT: 
       result = subtractValues(operand1, operand2); 
       break; 
      default: 
       break; 
     } 

     return result; 
    } 

    public double divideValues(double d1, double d2) { 
     double result; 
     if (d2 != 0) { 
      result = d1/d2; 
     } else { 
      // Avoid divide-by-zero error (could also throw it if preferred) 
      result = 0; 
     } 
     return result; 
    } 

    public double multiplyValues(double d1, double d2) { 
     double result = d1 * d2; 
     return result; 
    } 

    public double subtractValues(double d1, double d2) { 
     double result = d1 - d2; 
     return result; 
    } 

    public double addValues(double d1, double d2) { 
     double result = d1 + d2; 
     return result; 
    } 

    public static void main(String[] args) { 
     // Get and validate user input 
     String s1 = getInput("Enter a numeric value: "); 
     String s2 = getInput("Enter a numeric value: "); 
     String op = getInput("Enter 1=ADD, 2=Subtract, 3=Multiply, 4=Divide "); 

     // TODO: Handle NumberFormatExceptions here 
     double operand1 = Double.parseDouble(s1); 
     double operand2 = Double.parseDouble(s2); 
     OperatorType operator; 

     int opInt = Integer.parseInt(op); 
     switch (opInt) { 
      case 1: 
       operator = OperatorType.ADD; 
       break; 
      case 2: 
       operator = OperatorType.SUBTRACT; 
       break; 
      case 3: 
       operator = OperatorType.MULTIPLY; 
       break; 
      case 4: 
       operator = OperatorType.DIVIDE; 
       break; 

      default: 
       System.out.println("You entered an incorrect value"); 
       return; 
     } 

     // Use class to calculate result 
     Calculator calculator = new Calculator(); 
     double result = calculator.calculateResult(operand1, operand2, operator); 

     // Output results 
     System.out.println("The answer is " + result); 
    } 

    private static String getInput(String prompt) { 
     BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); 

     System.out.print(prompt); 
     System.out.flush(); 

     try { 
      return stdin.readLine(); 
     } catch (Exception e) { 
      return "error: " + e.getMessage(); 
     } 
    } 
} 
  • Всего ваших индивидуальных математических операций являются публичными методами класса Калькулятора, который может быть проверен индивидуально.
  • Основная математическая логика, которая принимает два операнда и оператора, находится в другом общедоступном методе, который также может быть проверен.
  • Пользовательский ввод и вывод остаются в основном методе, так как это логика (а не пользовательский ввод/вывод), которую вы хотите протестировать при автоматическом тестировании.
  • Все типы литья для ввода остаются в основном методе. Ваши методы должны работать с правильными типами данных, а не принимать строки в качестве входных данных, а затем попытаться их проанализировать. Оставьте синтаксический анализ (и обработку ошибок для синтаксического анализа) в основном методе.
+0

+1 - и имейте в виду, что те же функции, которые делают класс, проверяемый с помощью jUnit, также делают этот класс полезным при использовании в приложении. – slim

+0

признается, что я на самом деле не разработчик или на самом деле не должен создавать какие-либо из моих собственных классов, поэтому я не знал, что это проблема. –

-1

В тестировании JUnit вы можете включать в себя классы в тестовом файле. Нет необходимости копировать и вставлять код из класса и помещать его в тестовый файл. Он больше подойдет:

Калькулятор c = new Calculator();

c.myFunction();

Вы можете добавить утверждения assert в свою тестовую функцию, а также подтвердить, что вы получаете правильные результаты от вызова функции.

Я только что провел тесты JUnit с использованием Eclipse, но по существу вы создаете новый JUnit-файл (как и вы, класс) и автоматически настраиваете базовую структуру файла. Затем оттуда вы можете добавить сколько угодно тестов. Вы можете импортировать все классы, в которых вы нуждаетесь.

+0

JUnit - это просто java-инфраструктура, которая связана с языковыми законами, навязанными Java. Вы можете вызвать c.myFunction() извне c, только если myFunction находится вне этого класса. – GayashanNA

+0

Допустим, я пробовал что-то вроде этого: «Калькулятор mycalculator = new Calculator();» но это не сработало –

+0

Вы используете eclipse? Можете ли вы создать новый файл JUnit? – erics

1
  1. Displose of all static methods.
  2. В вашем основном экземпляре экземпляра Калькулятора и метода расчета прогона.
  3. Теперь вы можете проверить Calcultor вычислить метод с JUnit

Ограничение сферы для упаковки позволит Вам проверить этот класс, если тестовый класс будет в одном пакете (но в источнике тест)

public class Calculator { 

public static void main(String[] args) { 
    String s1 = getInput("Enter a numeric value: "); 
    String s2 = getInput("Enter a numeric value: "); 
    String op = getInput("Enter 1=ADD, 2=Subtract, 3=Multiply, 4=Divide "); 

new Calculator().calculate(s1, s2, op); 
} 

public void calculate(String s1, String s2, String op) 
    int opInt = Integer.parseInt(op); 
    double result = 0; 

    switch (opInt) { 
    case 1: 
     result = addValues(s1, s2); 
     break; 
    case 2: 
     result = subtractValues(s1, s2); 
     break; 
    case 3: 
     result = multiplyValues(s1, s2); 
     break; 
    case 4: 
     result = divideValues(s1, s2); 
     break; 

    default: 
     System.out.println("You entered an incorrect value"); 
     return; 
    } 

    System.out.println("The answer is " + result); 

} 

double divideValues(String s1, String s2) { 
    double d1 = Double.parseDouble(s1); 
    double d2 = Double.parseDouble(s2); 
    double result = d1/d2; 
    return result; 
} 

double multiplyValues(String s1, String s2) { 
    double d1 = Double.parseDouble(s1); 
    double d2 = Double.parseDouble(s2); 
    double result = d1 * d2; 
    return result; 
} 

double subtractValues(String s1, String s2) { 
    double d1 = Double.parseDouble(s1); 
    double d2 = Double.parseDouble(s2); 
    double result = d1 - d2; 
    return result; 
} 

double addValues(String s1, String s2) { 
    double d1 = Double.parseDouble(s1); 
    double d2 = Double.parseDouble(s2); 
    double result = d1 + d2; 
    return result; 
} 

String getInput(String prompt) { 
    BufferedReader stdin = new BufferedReader(
      new InputStreamReader(System.in)); 

    System.out.print(prompt); 
    System.out.flush(); 

    try { 
     return stdin.readLine(); 
    } catch (Exception e) { 
     return "error: " + e.getMessage(); 
    } 
} 
Смежные вопросы