-1

Im in IntellijIdea, trying to extract some logic from my tests to be reused in others. The problem is everytime I create another class (in the same test package); the test runs fine, but then stops finding the other file, throwing a 'java: cannot find symbol' error. It seems to happen whenever I make changes to the orginal file. It's the same for any new class I try to create, not just the abstract parent class in this example.

I've searched similar questions here, and because the test works at first this seemed promising IntelliJ can't find classes in same package when compiling. But, there were no scripts excepted when I checked.

Currently I'm running my unit tests by just right clicking my tests folder and selecting 'Run all tests', or just running the individual test the same way.

I would be very grateful for any insights.

EDIT: Thanks for fixing the image formatting issue for me. I also added the source code for the two classes as requested. I still feel like leaving the images is a good idea though, as I mainly meant to communicate the project structure and errors. Also, I want to stress that the problem is code independend I would say, since it persists with any two files.

Note that nonsensical line 51 of the InfoTest ("line = line;") was added to replicate the error. Any change to the original class causes any other class in the package to not be found. You can even see it's not present in the image showing the test running fine.

Extracted class:

package CommandProcessing;

import GameLogic.Game;
import org.junit.jupiter.api.BeforeEach;
import java.lang.reflect.Field;
import static org.junit.jupiter.api.Assertions.fail;

public abstract class InputSimulator {
    protected Game game;
    protected CommandParser commandParser;

    @BeforeEach
    void setUp() {
        game = new Game();
        try {
            Class<?> gameClass = game.getClass();
            Field cmdField = gameClass.getDeclaredField("commandParser");
            cmdField.setAccessible(true);
            commandParser = (CommandParser)cmdField.get(game);
        } catch (Exception e){
            fail(e);
        }
    }

    protected void simulateInput(String input){
        commandParser.handleInput(input);
    }

    class InputTestCase {
        private String input;
        private String expected;

        public InputTestCase(String input, String expected){
            this.input = input;
            this.expected = expected;
        }

        public String getInput() { return input; }

        public String getExpected() { return expected; }
    }
}

2

Original class:

package CommandProcessing;

import Database.*;
import GameLogic.Game;
import Ship.*;
import IOHandler.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.lang.reflect.Field;
import java.util.ArrayList;
import static org.junit.jupiter.api.Assertions.*;

class InfoTest extends InputSimulator {

    private final InputTestCase[] testCases =
    {
        new InputTestCase("info cpit", "Cockpit - health: 100.0, shields: 100.0"),
        new InputTestCase("info engi", "Engine - health: 100.0, shields: 100.0"),
        new InputTestCase("info shld", "Shields - health: 100.0, shields: 100.0"),
        new InputTestCase("info weap", "Weapons - health: 100.0, shields: 100.0"),
        new InputTestCase("info tank", "FuelTank - health: 100.0, shields: 100.0"),
        new InputTestCase("info carg", "CargoBay - health: 100.0, shields: 100.0")
    };

    @Test
    void printPartsOnInfo() {
        simulateInput("info");
        ArrayList<String> expected = new ArrayList<String>();
        expected.add(game.dbAccess().getMessage(Message.Info));
        for(PartType part : PartType.values()){
            String partString = part.toString();
            expected.add(partString);
        }
        ArchiveAccess archiveAccess = game.getArchiveAccess();
        ArrayList<String> lines = archiveAccess.getOutput();

        assertEquals(expected, lines);
    }

    @Test
    void printPartDetails() {
        for (InputTestCase testCase : testCases) {
            simulateInput(testCase.getInput());
            ArchiveAccess archiveAccess = game.getArchiveAccess();
            String line = archiveAccess.lastOutput();
            line = line;
            assertEquals(testCase.getExpected(), line);
        }
    }
}

1

All errors:

3

Test running fine the first time:

4

No Excludes:

5

mb569
  • 101
  • 1
  • 6
  • Is it reproducible with new sample project? – y.bedrov Dec 20 '20 at 18:55
  • Thanks, y.bedrov, trying to reproduce the error made me realise the problem! – mb569 Dec 20 '20 at 23:06
  • 1
    @zforgo and other downvoters: the "image of code" that got me downvoted actually held the answer. If you look at the errors and folder structure you could have seen that my Test folder is at the wrong level. The code itself only distracts from what the problem was, in my opinion. I feel you should have been more nuanced in this case. That being said I'll be very, very wary to have any code in my screenshot in future questions, as I didn't even know about this rule. – mb569 Dec 20 '20 at 23:33
  • 1
    as a side note it is better to avoid inheritance in tests. So don't create subclasses of tests from other tests – ACV Dec 21 '20 at 00:52
  • 1
    @ACV Thanks a lot for pointing that out! Researching it gave me some good insights. – mb569 Dec 21 '20 at 10:33

1 Answers1

0

So, the problem was that the test root folder was in my source folder!

I actually had the right answer at one time, but read it badly: How to create a test directory in Intellij 13?.

The test root folder should be next to a main folder which should be the one marked as the source root, not their parent 'src' folder. I had marked this parent directory as the source root - that is to say, the default source root was already called 'src' and I managed to put my test root folder in it, a project structure suspiciously hard to replicate as it would turn out. I got confused because of the naming.

It's a mystery to me how I got it to work in the first place, because when I tried to reproduce the problem it required some detours to get my test root inside my source root. And even then the tests couldn't even find the JUnit package at runtime (they did compile fine though).

mb569
  • 101
  • 1
  • 6