Testing a plugin: No file in project

Answered

Hi,

I want to write a JUNIT test for an Intellij Plugin that scans maven files (https://github.com/krasa/MavenHelper). This plugin needs
* Project
* MavenProject
* MavenArtifactNode

According this (https://www.jetbrains.org/intellij/sdk/docs/tutorials/writing_tests_for_plugins/completion_test.html) I should use LightJavaCodeInsightFixtureTestCase. Unfortunately I don't get in my test the needed variables:

```java
package krasa.mavenhelper.analyzer.action;

import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

import org.jetbrains.idea.maven.project.MavenProject;
import org.jetbrains.idea.maven.project.MavenProjectsManager;
import org.junit.Before;

public class PluginTest extends LightJavaCodeInsightFixtureTestCase {

private Project project;

@Override
protected String getTestDataPath() {
return "/home/stephan/workspaces/github/MavenHelper/src/test/resources/krasa/mavenhelper/analyzer/action";
}

@Before
public void setUp() throws Exception {
super.setUp();
this.project = getProject();
}

public void testSomething() throws Exception {
myFixture.configureByFiles("pom.xml");
VirtualFile virtualFile = myFixture.getFile().getVirtualFile();
MavenProjectsManager mavenProjectsManager = MavenProjectsManager.getInstance(project);
MavenProject mavenProject = mavenProjectsManager.findProject(virtualFile);

System.out.println("pom.xml exists: " + new File(getTestDataPath() + "/pom.xml").exists());
System.out.println("virtualFile: " + virtualFile);
System.out.println("mavenProject: " + mavenProject);
System.out.println("basePath: " + project.getBasePath() + " with files");
Files.walk(Paths.get(project.getBasePath())).forEach(System.out::println);
}

}
```

produces the output
```
pom.xml exists: true
virtualFile: temp:///src/pom.xml
mavenProject: null
basePath: /tmp/unitTest_something1 with files
/tmp/unitTest_something1
```

Why is mavenProject null? Why there are no files in temp basePath? What am I missing?

0
6 comments

Hi Stephan. The answer is simple - you did not imported project. I'd recommend you to make your class extends MavenImportingTestCase,

you can look at https://github.com/JetBrains/intellij-community/tree/master/plugins/maven/src/test/java/org/jetbrains/idea/maven for references

Then you can just rewrite your test like

public void testSomething() throws Exception {
createProjectPom("<groupId>test</groupId>" +
"<artifactId>project</artifactId>" +
"<version>1</version>");
importProject();
MavenProject mavenProject = myProjectsManager.findProject(virtualFile);
}
0

Hi Alexander,

 

thanks. How do I get access to MavenImportingTestCase? It's in src/test so I don't expect and don't find it in idea-IU-191.7141.44/plugins/maven/lib/maven.jar

 

Btw: How do you create a code-block here?

0

MavenImportingTestCase and related test classes are currently not published as separate artifacts, so you'll need to copy/paste them (or relevant bits).

0

Too bad, ok. Will dig through that file and try to adapt all needed steps.

0

I copied lots of stuff and got stuck because of

Caused by: com.intellij.execution.ExecutionException: Cannot start process, the working directory '/home/stephan/.cache/JetBrains/IntelliJIdea2020.1/plugins-sandbox/test/bin' does not exist
at com.intellij.execution.configurations.GeneralCommandLine.createProcess(GeneralCommandLine.java:377)
at com.intellij.execution.process.OSProcessHandler.startProcess(OSProcessHandler.java:98)
at com.intellij.execution.process.OSProcessHandler.<init>(OSProcessHandler.java:46)
at com.intellij.execution.process.OSProcessHandler$Silent.<init>(OSProcessHandler.java:307)
at org.jetbrains.idea.maven.server.MavenServerManager$MavenServerCMDState.startProcess(MavenServerManager.java:786)
at org.jetbrains.idea.maven.server.MavenServerManager$MavenServerCMDState.execute(MavenServerManager.java:777)
at com.intellij.execution.rmi.RemoteProcessSupport.startProcess(RemoteProcessSupport.java:205)
at com.intellij.execution.rmi.RemoteProcessSupport.acquire(RemoteProcessSupport.java:126)

 

This direcotry is used because of MavenServerManager is called with

SimpleJavaParameters createJavaParameters() {
SimpleJavaParameters params = new SimpleJavaParameters();
Sdk jdk = this.myServerManager.getJdk();
params.setJdk(jdk);
params.setWorkingDirectory(PathManager.getBinPath());

whereas PathManager.getBinPath() is resolved to the non-existing directory.

 

I don't know whether I should force to change the working directory or investigate why it does not exist or is not created. Honestly I didn't expect a working directory within my global intellij cache. All other directories in the test case are in /tmp/unitTest_something3/mavenTests

 

I'd really appreciate that you publish those test setups or provide me a workaround with published libs (like LightJavaCodeInsightFixtureTestCase).

0

Still trying to get it running. I tried to extract only the needed stuff for import

 

package krasa.mavenhelper.analyzer.action;

import static org.assertj.core.api.Assertions.assertThat;

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Collections;

import org.jetbrains.idea.maven.model.MavenExplicitProfiles;
import org.jetbrains.idea.maven.project.MavenProject;
import org.jetbrains.idea.maven.project.MavenProjectsManager;
import org.junit.Before;

public class PluginTest extends LightJavaCodeInsightFixtureTestCase {

private Project project;

@Override
protected String getTestDataPath() {
return "/home/stephan/workspaces/github/MavenHelper/src/test/resources/krasa/mavenhelper/analyzer/action";
}

@Before
public void setUp() throws Exception {
super.setUp();
this.project = getProject();
}

public void testSomething() throws Exception {

myFixture.configureByFiles("pom.xml");
VirtualFile virtualFile = myFixture.getFile().getVirtualFile();

MavenProjectsManager mavenProjectsManager = MavenProjectsManager.getInstance(project);
mavenProjectsManager.initForTests();

mavenProjectsManager.resetManagedFilesAndProfilesInTests(Collections.singletonList(virtualFile), new MavenExplicitProfiles(Collections.emptyList()));
ApplicationManager.getApplication().invokeAndWait(() -> {
try {
mavenProjectsManager.waitForReadingCompletion();
}
catch (Exception e) {
throw new RuntimeException(e);
}
});

ApplicationManager.getApplication().invokeAndWait(() -> {
mavenProjectsManager.waitForResolvingCompletion();
mavenProjectsManager.scheduleImportInTests(Collections.singletonList(virtualFile));
mavenProjectsManager.importProjects();
});

MavenProject mavenProject = mavenProjectsManager.findProject(virtualFile);

System.out.println("pom.xml exists: " + new File(getTestDataPath() + "/pom.xml").exists());
System.out.println("mavenProjectManager: " + mavenProjectsManager);
System.out.println("projectsTreeForTests: "+mavenProjectsManager.getProjectsTreeForTests());
System.out.println("virtualFile: " + virtualFile);
System.out.println("mavenProject: " + mavenProject);
System.out.println("basePath: " + project.getBasePath() + " with files");
Files.walk(Paths.get(project.getBasePath())).forEach(System.out::println);

assertThat(virtualFile).isNotNull();
assertThat(mavenProject).isNotNull();
}

}

but the maven project is still null
pom.xml exists: true
mavenProjectManager: org.jetbrains.idea.maven.project.MavenProjectsManager@48c53ca
projectsTreeForTests: MavenProjectsTree{myRootProjects=[], myProject=Project (name=light_temp, containerState=ACTIVE, componentStore=/tmp/unitTest_something1/light_temp.ipr) }
virtualFile: temp:///src/pom.xml
mavenProject: null
basePath: /tmp/unitTest_something1 with files
/tmp/unitTest_something1

Any suggestions with published features?

0

Please sign in to leave a comment.