java - 每次我尝试修复代码时都会发生 StackOverflowError

标签 java junit fractions stack-overflow greatest-common-divisor

我正在编写一个将 2 个分数相加的程序。我有 3 个类(class):UI、Rechnen 和 RechnenTest。给出了 UI 和 RechnenTest 类,我必须编写 Rechnen 类来添加分数。问题是,程序运行良好,但 JUnit 测试失败。这些是类:

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

public class UserInterface {
    public static void main(String[] args) {
        while (true) {
            String[] userData = getData_Dialog();
            if (userData == null)
                break;
            int z1 = 0;
            int n1 = 0;
            int z2 = 0;
            int n2 = 0;
            try {
                z1 = Integer.parseInt(userData[0]);
                n1 = Integer.parseInt(userData[1]);
                z2 = Integer.parseInt(userData[2]);
                n2 = Integer.parseInt(userData[3]);
            } catch (NumberFormatException e) {
                JOptionPane.showMessageDialog(null,
                        "Bitte nur ganze Zahlen eingeben, Nenner != 0");
                continue;
            }
            try {
                JOptionPane.showMessageDialog(null,
                        "Summe: " + Rechnen.bruchAddition(z1, n1, z2, n2));
            } catch (IllegalArgumentException e) {
                JOptionPane
                        .showMessageDialog(null,
                                "Mindestens eine der Zahlen war nicht im vorgebenen Bereich");
            }
        }
        JOptionPane.showMessageDialog(null, "Danke und auf Wiedersehen!");
        System.exit(0);
    }

    private static String[] getData_Dialog() {
        JTextField z1TF = new JTextField();
        JTextField n1TF = new JTextField();
        JTextField z2TF = new JTextField();
        JTextField n2TF = new JTextField();
        Object[] message = { "Zaehler 1", z1TF, "Nenner 1", n1TF, "Zaehler 2",
                z2TF, "Nenner 2", n2TF };
        Object[] options = { "Addition", "Abbruch" };
        int n = JOptionPane.showOptionDialog(new JFrame(), message,
                "Brueche Addieren", JOptionPane.YES_NO_OPTION,
                JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
        if (n == JOptionPane.OK_OPTION) { // Zustimmung
            return new String[] { z1TF.getText(), n1TF.getText(),
                    z2TF.getText(), n2TF.getText() };
        } else if (n == JOptionPane.NO_OPTION // Verneinung
                || n == JOptionPane.CLOSED_OPTION) { // Dialogfenster
                                                        // geschlossen
            return null;
        } else {
            return null;
        }
    }
}
<小时/>
import javax.swing.JOptionPane;


public class Rechnen {

    public static String bruchAddition(int z1, int n1, int z2, int n2)
            throws IllegalArgumentException {
        int m = (z1 * n2) + (z2 * n1);
        int n = (n1 * n2);

        if (n1 <= 0 || n2 <= 0 || z1 < 0 || z2 < 0) {
            throw new IllegalArgumentException();

        }
        return m / ggt(m, n) + "/" + n / ggt(m, n);

    }


    public static int max(int x, int y) {

        return x > y ? x : y;
    }


    public static int min(int x, int y) {

        return x > y ? y : x;
    }

    public static int ggt(int x, int y) {

        return (x == y) ? x : ggt(max(x, y) - min(x, y), min(x, y));
    }
}
<小时/>
import static org.junit.Assert.*;
import org.junit.Test;

public class RechnenTest {
    @Test
    public void test() {
        assertEquals("Zaehler = 1 Nenner = 1",
                rechnen.Rechnen.bruchAddition(1, 3, 2, 3));
        assertEquals("Zaehler = 1 Nenner = 1",
                rechnen.Rechnen.bruchAddition(5, 8, 3, 8));
        assertEquals("Zaehler = 1 Nenner = 1",
                rechnen.Rechnen.bruchAddition(10, 16, 3, 8));
        assertEquals("Zaehler = 1 Nenner = 3",
                rechnen.Rechnen.bruchAddition(-1, 3, 2, 3));
        assertEquals("Zaehler = -1 Nenner = 2",
                rechnen.Rechnen.bruchAddition(0, 2, -1, 2));
        assertEquals("Zaehler = -2 Nenner = 3",
                rechnen.Rechnen.bruchAddition(-1, 3, 1, -3));
        try {
            rechnen.Rechnen.bruchAddition(1, 1, 1, 0);
            fail();
        } catch (IllegalArgumentException e) {
            assertTrue(true);
        }
        try {
            rechnen.Rechnen.bruchAddition(Integer.MAX_VALUE, 1, 1, 1);
            fail();
        } catch (IllegalArgumentException e) {
            assertTrue(true);
        }
        assertEquals("Zaehler = 1 Nenner = " + Integer.MAX_VALUE,
                rechnen.Rechnen.bruchAddition(0, Integer.MAX_VALUE, 1,
                        Integer.MAX_VALUE));
    }
}

语言是德语。

谢谢

最佳答案

当我自己运行代码时,我得到:

org.junit.ComparisonFailure: expected:<[Zaehler = 1 Nenner = ]1> but was:<[1/]1>

测试期望 bruchAddition 返回具有不同格式的字符串。您可以通过将 bruchAddition 的最后一行更改为:

来解决该问题
return "Zaehler = " + m / ggt(m, n) + " Nenner = " + n / ggt(m, n);

这让我们完成了前三个断言,但随后对 Rechnen.bruchAddition(-1, 3, 2, 3) 的调用失败,并出现 IllegalArgumentException。这是因为 bruchAddition 会拒绝 z1 或 z2 < 0 的调用。

如果您将 bruchAddition 更改为接受负 z1 和 z2(根据单元测试的要求),则由于 ggt,您会收到 java.lang.StackOverflowError 递归地调用自身,显然没有正确结束递归。

你用ggtmaxmin寻找最大公约数的技术似乎被破坏了。 min(1, -3) 返回 -3。你确定这就是你想要的吗?我有一种感觉,在这种情况下,你的算法需要它返回 1,即最小的绝对值。

关于java - 每次我尝试修复代码时都会发生 StackOverflowError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20080919/

相关文章:

java - 在 Spring Boot 2 中验证 Oauth2 JWT token

junit - 如何只为多个 JUnit 测试准备一次状态

java - 类未找到异常 : While Executing Ant Script for JUNIT?

python - 如何使用 pyparsing 解析小数表达式?

java - 安卓 P : Service behavior changes

java - 无法在 Controller 中接收上传的文件 - Spring

java - 带有动画的 WindowManager(可能吗?)

Maven:在项目B中使用项目A的特定测试类

python - 如何在方程输出中保留分数

用R读取csv文件中的分数