我一直在尝试使用MavenCli
,将ByteArrayOutpurStream
- s设为stdout
和stderr
。
我有测试验证一些记录写入这些流。
只要我有一个测试,一切都没问题。
但是,如果我引入另一个测试,它会失败,因为没有任何内容写入stdout。
这是一个片段(Scala):
class MyIT extends SpecWithJUnit {
sequential
trait Ctx extends Scope {
val outStream = new ByteArrayOutpurStream()
val errStream = new ByteArrayOutpurStream()
val pomDir = Files.createTempDirectory("test_pom_").toFile
val mavenCli = new MavenCli()
def haveWrote(str: String): Matcher[Int] = {
contain(str) ^^ { (_: Int) =>
new String(outStream.toByteArray, "UTF-8") aka "written records" }
}
def maven(pom: Elem, goals: String*): Int = {
val pomFile = new File(pomDir, "pom.xml")
XML.save(pomFile.getCanonicalPath, pom)
System.setProperty(
"maven.multiModuleProjectDirectory",
pomDir.getCanonicalPath)
mavenCli.doMain(
goals.toArray,
pomDir.getCanonicalPath,
new PrintStream(outStream),
new PrintStream(errStream))
}
}
"test 1" should {
"write something" in new Ctx {
val pomXml =
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.company</groupId>
<artifactId>some-artifact-id</artifactId>
<version>1.0.0-SNAPSHOT</version>
<description>some meaningful description</description>
<name>some catchy name</name>
...
</project>
maven(pomXml, "clean" "validate") must haveWrote("something")
}
"write something else" in new Ctx {
val pomXml =
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.company</groupId>
<artifactId>some-artifact-id</artifactId>
<version>1.0.0-SNAPSHOT</version>
<description>some meaningful description</description>
<name>some catchy name</name>
... (different than the "write something" test)
</project>
maven(pomXml, "clean" "validate") must haveWrote("something else")
}
}
}
如果我评论"write something"
测试,则"write something else"
通过。
如果我评论"write something else"
测试(并取消注释"write something"
),则会"write something"
通过。
如果两者都被取消注释并执行,则会失败("write something else"
,因为它是连续的)。
在maven执行后添加println
-s outStream
,原因似乎是outStream
为空......
我无法弄清楚为什么,或者更重要的是,如何解决方法。
任何想法?...
提前致谢, 辖
答案 0 :(得分:0)
好的,我放弃了MavenCli
方法,转而支持Maven.execute(MavenExecutionRequest)
。这本身并没有解决问题,但我能够引入自己的ExecutionListener
,而不是默认的ExecutionEventLogger
。我的执行监听器直接记录记录,而不使用任何记录框架,这似乎解决了这个问题。
代码现在看起来像:
class MyIT extends SpecWithJUnit {
sequential
def plexusContainer = {
val containerConfig = new DefaultContainerConfiguration()
.setClassPathScanning(PlexusConstants.SCANNING_INDEX)
.setAutoWiring(true)
.setName("maven")
val container = new DefaultPlexusContainer(containerConfig)
container
}
def buildMavenRequest(pomFile: Path,
executionListener: ExecutionListener,
goals: String*): MavenExecutionRequest = {
val userProperties = new Properties()
val executionRequestPopulator = plexusContainer.lookup(classOf[MavenExecutionRequestPopulator])
val req = new DefaultMavenExecutionRequest()
.setPom(pomFile.toFile)
.setBaseDirectory(pomFile.getParent.toFile)
.setGoals(goals)
.setInteractiveMode(false)
.setExecutionListener(executionListener)
.setUserProperties(userProperties)
executionRequestPopulator.populateDefaults(req)
}
def maven(pomFile: Path,
executionListener: ExecutionListener,
goals: String*): MavenExecutionResult = {
val mavenRequest = buildMavenRequest(pomFile, executionListener, goals: _*)
val mvn = plexusContainer.lookup(classOf[Maven])
mvn.execute(mavenRequest)
}
def readFile(filename: Path): Seq[String] = {
Source.fromFile(filename.toString).getLines().foldLeft(Seq.empty[String]){ _ :+ _ }
}
trait Ctx extends Scope {
val pomDir = Files.createTempDirectory("test_pom_").toFile
val logFile = pomDir.resolve("test_log.log")
val myExecutionListener = new MyExecutionListener(logFile)
def haveWrote(str: String): Matcher[MavenExecutionResult] = {
contain(str) ^^ { (_: MavenExecutionResult) =>
readFile(logFile) aka "written records" }
}
}
"test 1" should {
"write something" in new Ctx {
val pomXml =
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.company</groupId>
<artifactId>some-artifact-id</artifactId>
<version>1.0.0-SNAPSHOT</version>
<description>some meaningful description</description>
<name>some catchy name</name>
...
</project>
maven(pomXml, "clean" "validate") must haveWrote("something")
}
"write something else" in new Ctx {
val pomXml =
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.company</groupId>
<artifactId>some-artifact-id</artifactId>
<version>1.0.0-SNAPSHOT</version>
<description>some meaningful description</description>
<name>some catchy name</name>
... (different than the "write something" test)
</project>
maven(pomXml, "clean" "validate") must haveWrote("something else")
}
}
}