Is it possible to have multiple source roots in unit tests?
In the plugin I'm developing, I need to verify that my custom action is available only in the test JVM source root (JavaSourceRootType.TEST_SOURCE
).
By default, the LightProjectDescritor
in the LightJavaCodeInsightFixtureTestCase
will create the temp:///src
directory and mark it as a source root.
For my test to be as close to reality as possible, I wanted to create two - a src/main/java
source root and a src/test/groovy
test source root.
The test would then verify that the action is available in one but not in the other source root.
I am not sure whether this is even possible. The LightTempDirTestFixtureImpl
relies on a single source root only. I can override the LightProjectDescritor
, LightTempDirTestFixtureImpl
and create a custom IdeaTestExecutionPolicy
, but this seems a bit complicated and I am not sure if this is the right way to go.
Also, I am not sure where is the right place to register my source roots and how to create them. The LightProjectDescriptor#createSourceRoot
only seems to accept a directory name rather than a path.
Please sign in to leave a comment.
You can simply add test sources directory programmatically in the specific test
Or provide custom
LightProjectDescriptor
and overrideconfigureModule()
Thanks Yann Cebron for the hints!
I aim to do this setup for all tests, so the
LightProjectDescriptor
will be the way to go.There is one catch though. I wanted the new
SpockLightProjectDescriptor
to be a standalone class, so I added the fixture as a constructor parameter.However, there is a circular dependency now
SpockLightProjectDescriptor
needsmyFixture
butmyFixture
isnull
until theLightProjectDescriptor.setup()
is called.LightProjectDescriptor.setup()
callsgetProjectDescriptor()
.I can workaround it of course, but I was wondering if I could do all the stuff in the
SpockLightProjectDescriptor
without the fixture.myFixture.testRootDisposable
would mean calling an internal API(module.project as ProjectEx).earlyDisposable
).When I commented out the suggested
Disposer.register(myFixture.getTestRootDisposable(), () -> PsiTestUtil.removeSourceRoot(getModule(), testRootDir));
code, I thought that meant the source root wouldn't be removed after every test. However, each test seems to start fresh with only thetemp://src
directory setup.There is another problem. If I follow your steps and create
src/main/java
, the action is available even though it's not in a real IntelliJ instance.When debugging, the
CreateTemplateInPackageAction#isAvailable()
returnstrue
in tests whereas in real instances it returnsfalse
when the action is run in thesrc/main/java
directory.Debugging more, the difference can be spotted in the attached pictures:
fileSet.root
points to thesrc/main/java
orsrc/main/kotlin
. All good here.fileSet.data.customContentRoot
differ. For the test it'snull
but in IntelliJ, it points tosrc/main
.It seems like the test setup is not the same as in real IntelliJ.
Sorry, but it's quite impossible to understand and reproduce your issues without access to the full sources.
Yeah, I understand. The sources are here: https://github.com/lobodpav/spock-intellij-plugin
Replication steps:
io.github.lobodpav.spock.action.NewSpockSpecificationActionIdeaSpec#The action is available only when Groovy and Spock are on the classpath
test.isAvailable
method returnstrue
formain/java
(which is incorrect and the action is unavailable in real IntelliJ).