hb1993 2022-02-22 10:37 采纳率: 50%
浏览 24
已结题

在 JUnit4 中使用 SystemOutRule 获取不到控制台的标准输出内容

问题遇到的现象和发生背景

自己在练习《Spring实战》第四版这本书的第一章例子时发现在测试部分无法使用 SystemOutRule 获取到 System.out 或者 PrintStream 输出到控制台的内容。

测试类

import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.StandardOutputStreamLog;
import org.junit.contrib.java.lang.system.SystemErrRule;
import org.junit.contrib.java.lang.system.SystemOutRule;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = KnightConfig.class)
public class SlayDragonQuestTest {
    @Rule
    public final StandardOutputStreamLog log = new StandardOutputStreamLog();

    @Rule
    public final SystemOutRule systemOutRule = new SystemOutRule().enableLog();

    @Rule
    public final SystemErrRule systemErrRule = new SystemErrRule().enableLog();

    @Autowired
    private Knight knight;

    @Test
    public void shouldBeNotNull() {
        Assert.assertNotNull(knight);
    }

    @Test
    public void writesTextToSystemErr() {
        System.err.print("hello world");
        Assert.assertEquals("hello world", systemErrRule.getLog());
    }

    @Test
    public void shouldBeEqual() {
        systemOutRule.clearLog();
        knight.embarkOnQuest();
//        System.out.println("Embarking on quest to slay the dragon!");
        Assert.assertEquals("Embarking on quest to slay the dragon!\r\n", systemOutRule.getLog());
    }
}

当我执行下面这个测试方法 shouldBeEqual(),结果显示 SystemOutRule 的 getLog() 方法获取的控制台输出内容是空的。

@Test
    public void shouldBeEqual() {
        systemOutRule.clearLog();
        knight.embarkOnQuest();
//        System.out.println("Embarking on quest to slay the dragon!");
        Assert.assertEquals("Embarking on quest to slay the dragon!\r\n", systemOutRule.getLog());
    }

img

点开 Click to see difference

img

显示 systemOutRule.getLog() 并没有获取到控制台的输出内容,而第一张结果图显示控制台是有输出内容的。

配置类

package com.hb.config;

import com.hb.impl.BraveKnight;
import com.hb.impl.SlayDragonQuest;
import com.hb.interfaces.Knight;
import com.hb.interfaces.Quest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class KnightConfig {
    @Bean
    public Knight knight() {
        return new BraveKnight(quest());
    }

    @Bean
    public Quest quest() {
        return new SlayDragonQuest(System.out);
    }
}

BraveKnight 类和 Knight 接口

public class BraveKnight implements Knight {
    private Quest quest;

    public BraveKnight(Quest quest) {
        this.quest = quest;
    }

    @Override
    public void embarkOnQuest() {
        quest.embark();
    }
}

public interface Knight {
    void embarkOnQuest();
}

SlayDragonQuest 类和 Quest 接口

package com.hb.impl;

import com.hb.interfaces.Quest;

import java.io.PrintStream;

public class SlayDragonQuest implements Quest {
    private PrintStream stream;

    public SlayDragonQuest(PrintStream stream) {
        this.stream = stream;
    }

    @Override
    public void embark() {
        stream.println("Embarking on quest to slay the dragon!");
    }
}

public interface Quest {
    void embark();
}
尝试过的解决方法

刚开始我以为是构造 SlayDragonQuest 类注入的 PrintStream 有问题,于是我新建了一个程序入口看看 BraveKnight 类的实际输出了什么。

package com.hb;

import com.hb.config.KnightConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Knight {
    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(KnightConfig.class);
        com.hb.interfaces.Knight knight = context.getBean(com.hb.interfaces.Knight.class);
        knight.embarkOnQuest();
        context.close();
    }
}

结果显示

img

说明通过 PrintStream 调用 Println() 方法是能够将内容输出到控制台的。那么也就说明了 SystemOutRule 的 getLog() 方法并没有获取到控制台的输出内容。接着我注释了测试方法 shouldBeEqual() 中的 knight.embarkOnQuest(); 而直接使用 System.out.println() 方法。

@Test
    public void shouldBeEqual() {
        systemOutRule.clearLog();
//        knight.embarkOnQuest();
        System.out.println("Embarking on quest to slay the dragon!");
        Assert.assertEquals("Embarking on quest to slay the dragon!\r\n", systemOutRule.getLog());
    }

结果还是一样失败

img


img

操作环境、软件版本

操作系统:Win10
IDE:Intellij IDEA 2021.1.2
依赖的包(pom.xml):

<dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>5.2.15.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>5.2.15.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.15.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>5.2.15.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>5.2.15.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>5.2.15.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.2.15.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>5.2.15.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-project-info-reports-plugin</artifactId>
      <version>3.0.0</version>
      <type>maven-plugin</type>
    </dependency>
    <dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-core</artifactId>
      <version>4.2.0</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.9.7</version>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.9</version>
    </dependency>
    <dependency>
      <groupId>com.github.stefanbirkner</groupId>
      <artifactId>system-rules</artifactId>
      <version>1.16.0</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-simple</artifactId>
      <version>1.7.25</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

在此请教下各位问题到底出在哪里

  • 写回答

0条回答 默认 最新

    报告相同问题?

    问题事件

    • 系统已结题 3月2日
    • 修改了问题 2月22日
    • 创建了问题 2月22日

    悬赏问题

    • ¥15 如何让企业微信机器人实现消息汇总整合
    • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
    • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
    • ¥15 TLE9879QXA40 电机驱动
    • ¥20 对于工程问题的非线性数学模型进行线性化
    • ¥15 Mirare PLUS 进行密钥认证?(详解)
    • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证
    • ¥20 想用ollama做一个自己的AI数据库
    • ¥15 关于qualoth编辑及缝合服装领子的问题解决方案探寻
    • ¥15 请问怎么才能复现这样的图呀