Checkstyle:使用@BeforeEach时测试中的HiddenField

问题描述 投票:0回答:1

在 Java 中创建 CLI 测试后,我收到 checkstyle 错误:

[ERROR] /src/src/test/java/com/doctestbot/cli/TestCliParser.java:53:23: 'supportedOptions' hides a field. [HiddenField]
[ERROR] /src/src/test/java/com/doctestbot/cli/TestCliParser.java:61:25: 'cliParser' hides a field. [HiddenField]

我认为这是因为在

supportedOptions
TestCliParser
方法中创建后,测试类
supportedOptions
的私有变量
testArgExists
掩盖了测试方法
@BeforeEach
中的同一个变量
setup()

我知道在类的某些函数中拥有一个可能被覆盖的 HiddenField 可能是不可取的,因此,我知道 Checkstyle 会抛出错误。我不太明白的是我是否应该使用不同的方法/策略来初始化

cliParser
supportedOptions
对象,或者我是否应该将它们以不同的方式传递给测试函数。

代码

这是相关的测试文件:

package com.doctestbot;

import com.doctestbot.cli.CliParser;


import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeEach;

import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.UnrecognizedOptionException;
import org.apache.commons.cli.ParseException;

/**
 * Test class for the CliParser class.
 * This class contains test methods to verify the functionality of the
 * CliParser class.
 */
@SuppressWarnings({"PMD.AtLeastOneConstructor"})
class TestCliParser {

    /** Object that is tested.
     */
    private CliParser cliParser;
    /** A custom set of supported options are created before each test for
     * testing.
    */
    private Options supportedOptions;

    /**
    This method sets up a dummy command-line parser with test options and
    arguments before each test.
    */
    @BeforeEach
    public void setup() {
        // Create the first option with the specified properties
        final Option.Builder firstOptBuilder = Option.builder("f");
        firstOptBuilder.required(true);
        firstOptBuilder.desc("The first option");
        firstOptBuilder.longOpt("first");
        final Option firstOption = firstOptBuilder.build();

        // Create the option for logging with the specified properties
        final Option.Builder optionLogBuilder = Option.builder("l");
        optionLogBuilder.required(true);
        optionLogBuilder.desc(
            "Log the full, unparsed ChatGPT output to the request"
            );
        optionLogBuilder.longOpt("log");
        final Option optionLog = optionLogBuilder.build();

        // Create the supported options set and add the options
        final Options supportedOptions = new Options();
        supportedOptions.addOption(firstOption);
        supportedOptions.addOption(optionLog);

        final String[] emptyArguments = {};

        // Create and initialize the CliParser instance with dummy arguments
        @SuppressWarnings({"PMD.UnusedLocalVariable"})
        final CliParser cliParser = new CliParser(emptyArguments);
    }

    /**
     * Test method to verify the CLI verification function works if it receives
     * expected arguments.
     */
    @Test
    void testArgExists() {
        // Dummy command-line arguments for testing
        final String[] dummyArguments = {"-f", "theValueOfA", "--log"};

        // Verify no error is thrown upon valid arguments.
         assertDoesNotThrow(() -> cliParser.verifyArgsAreSupported(
            supportedOptions, dummyArguments));
    }

    /**
     * Test method to verify the verifyArgsAreSupported method throws an error
     * if an unexpected argument is passed.
     */
    @Test
    @SuppressWarnings({"PMD.JUnitTestContainsTooManyAsserts",
    "PMD.LawOfDemeter"})
    void testUnknownArgThrowsError() {

        // Dummy command-line arguments for testing
        final String[] dummyArguments = {"-f", "theValueOfA", "--log",
        "--someUnsupportedArg"};

        // Verify that the provided arguments match the supported options


        // Assert that the UnrecognizedOptionException is thrown and its cause
        // is ParseException.
         final Exception exception = assertThrows(
            UnrecognizedOptionException.class, () -> {
            cliParser.verifyArgsAreSupported(supportedOptions, dummyArguments);
        });


        // Assert the cause of the UnrecognizedOptionException
        final Throwable cause = exception.getCause();
        assertTrue(cause instanceof ParseException,
        "The error was thrown due to a ParseException.");
    }
}

问题

如何解决 HiddenField 错误,同时仍在

cliParser
supportedOptions
函数中初始化
@BeforeEach
setup()

编辑回复评论

我在评论中指出的错误对我来说是有道理的。然而,当我改变时:

final Options supportedOptions = new Options();

至:

supportedOptions = new Options();

Checkstyle 抛出错误:

checkstyle...............................................................Failed
- hook id: checkstyle
- exit code: 254

Starting audit...
com.puppycrawl.tools.checkstyle.api.CheckstyleException: Exception was thrown while processing src/test/java/com/doctestbot/cli/TestCliParser.java
    at com.puppycrawl.tools.checkstyle.Checker.processFiles(Checker.java:306)
    at com.puppycrawl.tools.checkstyle.Checker.process(Checker.java:223)
    at com.puppycrawl.tools.checkstyle.Main.runCheckstyle(Main.java:415)
    at com.puppycrawl.tools.checkstyle.Main.runCli(Main.java:338)
    at com.puppycrawl.tools.checkstyle.Main.execute(Main.java:195)
    at com.puppycrawl.tools.checkstyle.Main.main(Main.java:130)
Caused by: com.puppycrawl.tools.checkstyle.api.CheckstyleException: IllegalStateException occurred while parsing file /src/src/test/java/com/doctestbot/cli/TestCliParser.java.
    at com.puppycrawl.tools.checkstyle.JavaParser.parse(JavaParser.java:105)
    at com.puppycrawl.tools.checkstyle.TreeWalker.processFiltered(TreeWalker.java:152)
    at com.puppycrawl.tools.checkstyle.api.AbstractFileSetCheck.process(AbstractFileSetCheck.java:98)
    at com.puppycrawl.tools.checkstyle.Checker.processFile(Checker.java:334)
    at com.puppycrawl.tools.checkstyle.Checker.processFiles(Checker.java:293)
    ... 5 more
Caused by: java.lang.IllegalStateException: 37:61: mismatched input '(' expecting ';'
    at com.puppycrawl.tools.checkstyle.JavaParser$CheckstyleErrorListener.syntaxError(JavaParser.java:255)
    at org.antlr.v4.runtime.ProxyErrorListener.syntaxError(ProxyErrorListener.java:41)
    at org.antlr.v4.runtime.Parser.notifyErrorListeners(Parser.java:544)
    at org.antlr.v4.runtime.DefaultErrorStrategy.reportInputMismatch(DefaultErrorStrategy.java:327)
    at org.antlr.v4.runtime.DefaultErrorStrategy.reportError(DefaultErrorStrategy.java:139)
    at com.puppycrawl.tools.checkstyle.CheckstyleParserErrorStrategy.recoverInline(CheckstyleParserErrorStrategy.java:38)
    at org.antlr.v4.runtime.Parser.match(Parser.java:208)
    at com.puppycrawl.tools.checkstyle.grammar.java.JavaLanguageParser.blockStatement(JavaLanguageParser.java:6189)
    at com.puppycrawl.tools.checkstyle.grammar.java.JavaLanguageParser.block(JavaLanguageParser.java:6100)
    at com.puppycrawl.tools.checkstyle.grammar.java.JavaLanguageParser.methodBody(JavaLanguageParser.java:2939)
    at com.puppycrawl.tools.checkstyle.grammar.java.JavaLanguageParser.methodDeclaration(JavaLanguageParser.java:2897)
    at com.puppycrawl.tools.checkstyle.grammar.java.JavaLanguageParser.memberDeclaration(JavaLanguageParser.java:2744)
    at com.puppycrawl.tools.checkstyle.grammar.java.JavaLanguageParser.classBodyDeclaration(JavaLanguageParser.java:2670)
    at com.puppycrawl.tools.checkstyle.grammar.java.JavaLanguageParser.classBody(JavaLanguageParser.java:2476)
    at com.puppycrawl.tools.checkstyle.grammar.java.JavaLanguageParser.classDeclaration(JavaLanguageParser.java:1095)
    at com.puppycrawl.tools.checkstyle.grammar.java.JavaLanguageParser.types(JavaLanguageParser.java:752)
    at com.puppycrawl.tools.checkstyle.grammar.java.JavaLanguageParser.typeDeclaration(JavaLanguageParser.java:666)
    at com.puppycrawl.tools.checkstyle.grammar.java.JavaLanguageParser.compilationUnit(JavaLanguageParser.java:413)
    at com.puppycrawl.tools.checkstyle.JavaParser.parse(JavaParser.java:99)
    ... 9 more
Caused by: org.antlr.v4.runtime.InputMismatchException
    ... 23 more
Checkstyle ends with 1 errors.
java checkstyle hidden-field
1个回答
0
投票

通过实施评论中给出的建议找到了解决方案:

package com.doctestbot;

import com.doctestbot.cli.CliParser;


import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeEach;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.UnrecognizedOptionException;
import org.apache.commons.cli.ParseException;

/**
 * Test class for the CliParser class.
 * This class contains test methods to verify the functionality of the
 * CliParser class.
 */
@SuppressWarnings({"PMD.AtLeastOneConstructor"})
class TestCliParser {

    /** Object that is tested.
     */
    private CliParser cliParser;
    /** A custom set of supported options are created before each test for
     * testing.
    */
    private Options supportedOptions;

    /**
    This method sets up a dummy command-line parser with test options and
    arguments before each test.
    */
    @BeforeEach
    public void setup() {
        // Create the first option with the specified properties
        final Option.Builder firstOptBuilder = Option.builder("f");
        firstOptBuilder.required(true);
        firstOptBuilder.desc("The first option");
        firstOptBuilder.longOpt("first");
        final Option firstOption = firstOptBuilder.build();

        // Create the option for logging with the specified properties
        final Option.Builder optionLogBuilder = Option.builder("l");
        optionLogBuilder.required(true);
        optionLogBuilder.desc(
            "Log the full, unparsed ChatGPT output to the request"
            );
        optionLogBuilder.longOpt("log");
        final Option optionLog = optionLogBuilder.build();

        setSupportedOptions(firstOption, optionLog);
        setCliParser();
    }

    /**
     * Test method to verify the CLI verification function works if it receives
     * expected arguments.
     */
    @Test
    void testArgExists() {
        // Dummy command-line arguments for testing
        final String[] dummyArguments = {"-f", "theValueOfA", "--log"};

        // Verify no error is thrown upon valid arguments.
         assertDoesNotThrow(() -> cliParser.verifyArgsAreSupported(
            supportedOptions, dummyArguments));
    }

    /**
     * Test method to verify the verifyArgsAreSupported method throws an error
     * if an unexpected argument is passed.
     */
    @Test
    @SuppressWarnings({"PMD.JUnitTestContainsTooManyAsserts",
    "PMD.LawOfDemeter"})
    void testUnknownArgThrowsError() {

        // Dummy command-line arguments for testing
        final String[] dummyArguments = {"-f", "theValueOfA", "--log",
        "--someUnexpectedArgument"};

        // Verify that the provided arguments match the supported options


        // Assert that the UnrecognizedOptionException is thrown and its cause
        // is ParseException.
         final Exception exception = assertThrows(
            UnrecognizedOptionException.class, () -> {
            cliParser.verifyArgsAreSupported(supportedOptions, dummyArguments);
        });


        // Assert the cause of the UnrecognizedOptionException
        final Throwable cause = exception.getCause();
        assertTrue(cause instanceof ParseException,
        "The error was thrown due to a ParseException.");
    }


    /**
     * Getter method for the supportedOptions.
     *
     * @return The supported options.
     */
    public CliParser getCliParser() {
        return cliParser;
    }

    /**
     * Sets the supported options for testing.
     */
    @SuppressWarnings({"PMD.DetachedTestCase"})
    public void setCliParser() {

        final String[] emptyArguments = {};
        // Create and initialize the CliParser instance with dummy arguments
        // @SuppressWarnings({"PMD.UnusedLocalVariable"})
        cliParser = new CliParser(emptyArguments);
    }

     /**
     * Getter method for the supportedOptions.
     *
     * @return The supported options.
     */
    public Options getSupportedOptions() {
        return supportedOptions;
    }

    /**
     * Sets the supported options for testing.
     *
     * @param firstOption The first option to add.
     * @param optionLog The option for logging.
     */
    public void setSupportedOptions(final Option firstOption,
    final Option optionLog) {
        // Create the supported options set and add the options
        supportedOptions = new Options();
        supportedOptions.addOption(firstOption);
        supportedOptions.addOption(optionLog);
    }
}

通过将两个私有字段的初始化移动到单独的 setter 和 getter 方法中,并从

@BeforeEach
setup()
方法调用这些方法,解决了额外的错误。没有必要在测试中创建测试类的对象/构造函数来使用
this.supportedOptions
调用私有字段。相反,我可以将它们保留为测试的全局变量。

© www.soinside.com 2019 - 2024. All rights reserved.