【问题标题】:Main method doesn't run program in spite of all tests passing尽管所有测试都通过了,但 Main 方法不运行程序
【发布时间】:2021-10-06 22:04:03
【问题描述】:

我正在用 Java 制作一个测验应用程序,并正在使用 JUnit 来测试我的方法。现在,我的 src 文件夹有一个主文件夹。主文件夹还有两个包,模型和 UI。模型包包含一个名为 QuizQuestions 的类并包含数据建模。 UI 包有 2 个类,Quiz 和 Main。 Quiz 类向 QuizQuestions 类提供打印语句,而 Main 类具有 Main 方法。代码如下:

QuizQuestions 类(模型):

package model;

import ui.Quiz;

import java.util.*;

public class QuizQuestions {

    Map<String, String> questionsAndAnswers;
    Quiz quiz;

    // REQUIRES: the map data structure, specifically the field named questionsAndAnswers
    // MODIFIES: nothing
    // EFFECTS: creates a new linked hashmap by the name questionsAndAnswers
    public QuizQuestions() {
        questionsAndAnswers = new LinkedHashMap<>();
    }

    // REQUIRES: nothing
    // MODIFIES: this
    // EFFECTS: adds the questions and answers to the linked list in an ordered format
    public LinkedHashMap<String, String> entireQuestionsList() {
        questionsAndAnswers.put("Purpose of spinning jenny in the Industrial Revolution ",
                "\na)A device for making cloth\nb)A device for storing energy\nc)A steam engine\nd)A water pump\n\n");
        questionsAndAnswers.put("A city NOT founded by the Romans ", "\na)Alexandria\nb)Berlin\nc)London\nd)None\n\n");
        questionsAndAnswers.put("Number of wives Henry VIII had ", "\na)1\nb)6\nc)3\nd)2\n");
        questionsAndAnswers.put("Country of origin of Zoroastrianism ", "\na)Brazil\nb)Egypt\nc)Persia\nd)India\n\n");
        questionsAndAnswers.put("The person who captured Moscow for the last time in history ",
                "\na)No one\nb)Hitler\nc)Napoleon\nd)Ogedei Khan\n\n");
        questionsAndAnswers.put("First time the Winter Olympics were held in ",
                "\na)1896\nb)1900\nc)1888\nd)1924\n\n");
        questionsAndAnswers.put("Number of chapters in the Olympic Charter ", "\na)5\nb)6\nc)7\nd)8\n\n");
        questionsAndAnswers.put("Designer of the trophy of FIFA Women’s World Cup? ",
                "\na)William Sawaya\nb)Formiga\nc)Marta\nd)Sun Wen\n\n");
        questionsAndAnswers.put("The Mission Hills World Cup is related to ", "\na)Golf\nb)Polo\nc)TT\nd)Chess\n\n");
        questionsAndAnswers.put("Number of players who have reached the 100-goal mark in EPL ",
                "\na)5\nb)10\nc)28\nd)30\n\n");
        questionsAndAnswers.put("Location of the Spanish Steps ", "\na)Rome\nb)Lisbon\nc)Madrid\nd)Barcelona\n\n");
        questionsAndAnswers.put("Total number of provinces in Canada ", "\na)5\nb)10\nc)30\nd)20\n\n");
        questionsAndAnswers.put("A popular Middle Eastern dish ", "\na)Pasta\nb)Dolma\nc)Pizza\nd)Curry\n\n");
        questionsAndAnswers.put("Location of the Chocolate Hills ",
                "\na)Pakistan\nb)Japan\nc)Philippines\nd)India\n\n");
        questionsAndAnswers.put("The tallest building amongst the following is ",
                "\na)The Shard\nb)Burj Khalifa\nc)Skytree\nd)Moscow Tower\n\n");
        return (LinkedHashMap<String, String>) questionsAndAnswers;
    }

    // REQUIRES: questionsAndAnswers linked list should not be empty
    // MODIFIES: nothing
    // EFFECTS: gets the questions and answers from the linked list
    // and displays one question and its corresponding answers one after
    // the other while providing the user the option to enter his/her answer
    // for each question.
    public ArrayList<String> askQuestionsOneByOne() {
        quiz = new Quiz();
        Set<Map.Entry<String, String>> entry = questionsAndAnswers.entrySet();
        ArrayList<String> userAnswer = new ArrayList<>();
        for (Object o : entry) {
            System.out.println(o);
            String answer = quiz.askUser();
            userAnswer.add(answer);
        }
        return userAnswer;
    }

    // REQUIRES: nothing
    // MODIFIES: this
    // EFFECTS: adds the correct answers of all the questions to
    // a linked list and returns that list.
    public ArrayList<String> storeCorrectAnswers() {
        ArrayList<String> correctAnswers = new ArrayList<>();
        correctAnswers.add("a");
        correctAnswers.add("a");
        correctAnswers.add("b");
        correctAnswers.add("c");
        correctAnswers.add("c");
        correctAnswers.add("d");
        correctAnswers.add("b");
        correctAnswers.add("a");
        correctAnswers.add("a");
        correctAnswers.add("d");
        correctAnswers.add("a");
        correctAnswers.add("b");
        correctAnswers.add("b");
        correctAnswers.add("c");
        correctAnswers.add("b");
        return correctAnswers;
    }

    // REQUIRES: storeCorrectAnswers and askQuestionsOneByOne is not empty
    // MODIFIES: nothing
    // EFFECTS: stores the answers obtained from storeCorrectAnswers and
    // askQuestionsOneByOne into 2 new linked lists and compares both of
    // them. Whenever the answer at a particular index in both the lists
    // is the same, the score of the user is incremented by 1 and the
    // total score is returned at the end of the method.
    public int compareAnswers() {
        ArrayList<String> userAnswers = storeCorrectAnswers();
        ArrayList<String> correctAnswers = askQuestionsOneByOne();
        int score = 0;
        for (int i = 0; i < userAnswers.size(); i++) {
            if (userAnswers.get(i).equals(correctAnswers.get(i))) {
                score++;
            }
        }
        return score;
    }

    // REQUIRES: the value of the score variable from compareAnswers()
    // MODIFIES: nothing
    // EFFECTS: displays the score of the user and according to the score,
    // displays a message informing the user about how good the score is.
    public void displayScoreAndPerformanceMessage() {
        quiz = new Quiz();
        int score = compareAnswers();
        quiz.printScore();
        if (score < 5 && score > 0) {
            quiz.messageForScoreLessThanFive();
            askUserToPlayAgain();
        } else if (score >= 5 && score < 10) {
            quiz.messageForScoreMoreThanFiveAndLessThanTen();
            askUserToPlayAgain();
        } else if (score >= 10 && score != 15) {
            quiz.messageGorScoreMoreThanTenAndLessThanFifteen();
            askUserToPlayAgain();
        } else {
            quiz.messageForPerfectScore();
        }
    }

    // REQUIRES: the list of quiz questions and the user score
    // MODIFIES: converts the user answer to lower case if he/she enters
    // the response in uppercase.
    // EFFECTS: gives the user the option to play the quiz again
    // and based on the answer, starts the quiz from scratch or exits the program
    public void askUserToPlayAgain() {
        quiz = new Quiz();
        String response = quiz.askUserForPlayingAgain();
        while (response.equalsIgnoreCase("y")) {
            entireQuestionsList();
            displayScoreAndPerformanceMessage();
            askUserToPlayAgain();
        }
        if (response.equalsIgnoreCase("n")) {
            quiz.thankYouMessage();
            System.exit(1);
        } else {
            quiz.errorMessage();
            askUserToPlayAgain();
        }
    }
}

测验类(UI):

package ui;

import model.QuizQuestions;

import java.util.Scanner;

public class Quiz {

    Quiz qz;

    public Quiz() {
        qz = new Quiz();
    }

    public void displayGreeting() {
        System.out.println("Welcome to the quiz application!\n\nHere are the quiz questions.");
    }

    // REQUIRES: nothing
    // MODIFIES: nothing
    // EFFECTS: allows the user to enter their answer for
    // each question and returns that answer.
    public String askUser() {
        Scanner sc = new Scanner(System.in);
        return sc.next();
    }

    // REQUIRES: score from the compareAnswers method in QuizQuestions
    // MODIFIES: nothing
    // EFFECTS: displays the score of the user on the screen
    public void printScore() {
        QuizQuestions qq = new QuizQuestions();
        int score = qq.compareAnswers();
        System.out.println("Your score is " + score);
    }

    // EFFECTS: displays a particular message if the user score is less than 5
    public void messageForScoreLessThanFive() {
        System.out.println("Looks like your general knowledge is weak. Try to read books!");
    }

    // EFFECTS: displays a particular message if the user score is more than 5
    // but less than 10.
    public void messageForScoreMoreThanFiveAndLessThanTen() {
        System.out.println("You are doing good! There is still potential to improve though!");
    }

    // EFFECTS: displays a particular message if the user score is more than 10
    // but less than 15.
    public void messageGorScoreMoreThanTenAndLessThanFifteen() {
        System.out.println("You are awesome! Your score is better than most of the people!");
    }

    // EFFECTS: displays a particular message if the user score is equal to 15.
    public void messageForPerfectScore() {
        System.out.println("Perfect score! Congratulations!");
    }

    // EFFECTS: asks the user whether he/she wants to play again and prompts them for a response.
    public String askUserForPlayingAgain() {
        System.out.println("Do you want to play the quiz again? (Y)es/(N)o?\n");
        Scanner scanner = new Scanner(System.in);
        return scanner.next();
    }

    // EFFECTS: displays a thank-you message at the end of the program.
    public void thankYouMessage() {
        System.out.println("Thanks for playing!\n");
    }

    // EFFECTS: displays an error message if the user does not select a right option
    public void errorMessage() {
        System.out.println("Please enter a valid response.\n");
    }

}

主要方法:

package ui;

import model.QuizQuestions;

public class Main {
    public static void main(String[] args) {
        QuizQuestions qq = new QuizQuestions();
        qq.entireQuestionsList();
        qq.askQuestionsOneByOne();
        qq.compareAnswers();
        qq.displayScoreAndPerformanceMessage();
        qq.askUserToPlayAgain();
    }
}

我所有的测试都通过了,但是当我尝试从 main 方法运行我的程序时,它没有运行。我哪里错了?

谢谢

【问题讨论】:

  • 您是否遇到任何错误?
  • 是的,QuizQuestions 类中的 quiz 对象出现空指针异常
  • 您在使用之前是否在QuizQuestions 类中创建了new Quiz? =] 还有一件事,为什么Quiz 类中有Quiz 的实例?
  • 是的,我这样做了,但是当我这样做时,我的测试都没有通过。我将删除 Quiz 实例

标签: java debugging testing junit compiler-errors


【解决方案1】:

您的代码存在一些问题。我将在这里总结它们:

  1. 删除 Quiz 类的构造函数中的 qz = new Quiz() 行,这会导致堆栈溢出,因为它会一次又一次地运行构造函数。
  2. 代码中的另一个主要问题是,它没有保存得分值以供打印和其他用途,而是不断初始化新的测验并在这些新实例中运行 compareAnswers()。您需要将分数值保存在 Quiz 类中,并使用该存储值。
  3. 最后,在 askQuestionsOneByOne() 中,您将返回用户答案,但永远不要使用它们。相反,在 compareAnswers() 中,您再次初始化新列表。

您可以通过添加分数字段来修复 Quiz 类(下面的第一个代码示例)。然后,在主类中,当您运行返回分数的 compareAnswers() 时,将其保存到当前测验(下面的第二个代码示例)。随后,当您需要分数时,例如在 displayScoreAndPerformance() 调用中,从测验对象中检索它。 Quiz 对象中的 printScore() 也是如此。为此,您需要在 QuizQuestions 中为 Quiz 对象添加 getter 和 setter。

最后,您需要参数化 compareAnswers 以接受用户的答案,并在 main 方法中将 askQuestionsOneByOne() 的结果传递给 compareAnswers()。

public class Quiz {

    int score;

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }
public class Main {
    public static void main(String[] args) {

        ArrayList<String> userAnswers = new ArrayList<>();

        QuizQuestions qq = new QuizQuestions();
        qq.entireQuestionsList();
        userAnswers = qq.askQuestionsOneByOne();
        qq.getQuiz().setScore(qq.compareAnswers(userAnswers));
        qq.displayScoreAndPerformanceMessage();
        qq.askUserToPlayAgain();
    }
}


 public void displayScoreAndPerformanceMessage() {
        // quiz = new Quiz();
        //int score = compareAnswers();
        int score = quiz.getScore();
        quiz.printScore();
        if (score < 5 && score > 0) {
            quiz.messageForScoreLessThanFive();
            askUserToPlayAgain();
        } else if (score >= 5 && score < 10) {
            quiz.messageForScoreMoreThanFiveAndLessThanTen();
            askUserToPlayAgain();
        } else if (score >= 10 && score != 15) {
            quiz.messageGorScoreMoreThanTenAndLessThanFifteen();
            askUserToPlayAgain();
        } else {
            quiz.messageForPerfectScore();
        }
    }
 public void printScore() {
      //  QuizQuestions qq = new QuizQuestions();
       // int score = qq.compareAnswers();
        System.out.println("Your score is " + score);
    }
public class QuizQuestions {

    Map<String, String> questionsAndAnswers;
    Quiz quiz;

    public Quiz getQuiz() {
        return quiz;
    }

    public void setQuiz(Quiz quiz) {
        this.quiz = quiz;
    }
    public int compareAnswers(ArrayList<String> userAnswers) {
        ArrayList<String> correctAnswers = storeCorrectAnswers();
        int score = 0;
        for (int i = 0; i < userAnswers.size(); i++) {
            if (userAnswers.get(i).equals(correctAnswers.get(i))) {
                score++;
            }
        }
        return score;
    }

【讨论】:

  • 感谢详细的回复!但是,我的应用程序现在运行了两次,再次询​​问问题,然后分数显示不正确。它总是 0
  • 我在之前的解释中遗漏了一件事,为了完整起见,我对其进行了编辑。
  • 是的,它在第一次尝试时运行良好,但是当我点击 y 后,当它询问我是否再次播放并回答所有问题时,分数保持为 0。我目前正在努力
  • 存在的问题可能比您在此问题中发布的问题更多,是的。我会将 askUserToPlayAgain() 部分移到主类中,或者至少移到 QuizQuestions 类之外。它是一个应用程序工作流主题,只是重新运行主类的与上次运行相同的部分。
猜你喜欢
  • 1970-01-01
  • 2023-03-12
  • 2016-08-09
  • 2023-04-01
  • 2018-09-06
  • 1970-01-01
  • 2021-09-22
  • 2021-10-29
  • 1970-01-01
相关资源
最近更新 更多