简体   繁体   English

Junit-测试不同的类

[英]Junit - testing a different class

Hi I'm trying to get my head around Junit testing and I can't find a way to test another class without copy pasting parts of it in. say I want to test this: 嗨,我正在努力让我了解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();
    }
}

Is there any way I can set up the JUnit case test to check parts of this without copy and pasting it in for every test or modifying the orginal class. 有什么方法可以设置JUnit案例测试来检查其中的部分内容,而无需复制并粘贴到每个测试中或修改原始类。 am I missing something or is this something Junit can't do? 我是否缺少某些东西,或者Junit无法做到?

Here is what I'm at so far: 这是我到目前为止的内容:

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);
}

}

The design of your class doesn't really lend itself to automated testing. 您的班级设计并不能真正用于自动化测试。

  • The only methods in the class are private static, meaning that they can only be accessed from other static methods inside this class (though it is possible to use Reflection to overcome this if you absolutely must have private static members.) 该类中唯一的方法是私有静态方法,这意味着只能从该类内部的其他静态方法中访问它们(尽管如果绝对必须具有私有静态成员,则可以使用Reflection来克服这一点。)
  • Parts of the class require user input / intervention, which makes it difficult to test them automatically. 该课程的某些部分需要用户输入/干预,这使得自动测试变得困难。
  • Your class isn't object-oriented. 您的课程不是面向对象的。 It is written more like a functional program (eg C), with a main body and global functions, rather than written as an object that provides functionality. 它更像具有主体和全局功能的功能程序(例如C)编写,而不是作为提供功能的对象编写。

Try something like this instead: 尝试这样的事情:

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();
        }
    }
}
  • All of your individual mathematical operations are public methods of the Calculator class, which can be tested individually. 您所有的单独数学运算都是Calculator类的公共方法,可以单独进行测试。
  • The main mathematical logic, which takes two operands and an operator, is in another public method, which can be tested too. 包含两个操作数和一个运算符的主要数学逻辑在另一种公共方法中,也可以对其进行测试。
  • User input and output stays in the main method, as it is the logic (not the user input/output) that you want to test with automated testing. 用户输入和输出保留在main方法中,因为它是您要使用自动测试进行测试的逻辑(不是用户输入/输出)。
  • All type casting for input remains in the main method. 输入的所有类型转换都保留在main方法中。 Your methods should operate on the correct data types, not take Strings as input and then try to parse those. 您的方法应该对正确的数据类型进行操作,而不是将Strings作为输入,然后尝试解析它们。 Leave the parsing (and error-handling for the parsing) in the main method. 将解析(以及解析的错误处理)留在main方法中。
  1. Displose of all static methods. 放弃所有静态方法。
  2. In your main create instance of Calculator and run calculate method. 在您的Calculator的主要创建实例中,并运行calculate方法。
  3. Now you can test Calcultor calculate method with JUnit 现在您可以使用JUnit测试Calcultor的计算方法

Restricting scope to package will enable you to test this class, if test class will be in same package (but in test source) 如果测试类在同一个程序包中(但在测试源中),则将范围限制为包将使您能够测试此类

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();
    }
}

In JUnit testing you can include classes in your test file. 在JUnit测试中,您可以在测试文件中包含类。 There is no need to copy and paste code from a class and put it in the test file. 无需复制和粘贴类中的代码并将其放入测试文件中。 It would look more like: 它看起来更像:

Calculator c = new Calculator(); 计算器c =新的Calculator();

c.myFunction(); c.myFunction();

You can add assert statements into your test function as well to confirm that you are getting the correct results from the function call. 您也可以在测试函数中添加断言语句,以确认从函数调用中获得正确的结果。

I have only done JUnit tests using Eclipse, but essentially you create a new JUnit file (just like you would a Class), and that automatically sets up the basic structure of the file. 我仅使用Eclipse完成了JUnit测试,但实际上您创建了一个新的JUnit文件(就像对Class一样),并且该文件自动设置了文件的基本结构。 Then from there you can add in however many tests you want. 然后,您可以从那里添加所需的许多测试。 You may import whatever classes you need as well. 您也可以导入所需的任何类。

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

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