【发布时间】:2021-07-07 20:12:39
【问题描述】:
我正在学习使用 Junit 和 Mockito 框架进行单元测试和双重测试,但是在使用“模拟”的特定测试中我没有得到预期的结果。我做了一个assertThat,它应该返回正面测试,相反,它返回一个错误,上面写着Mockito cannot mock this class。它是一个名为“控制台”的类,它必须从用户的键盘打印和收集值,但是当然,在单元测试中,这应该被“模拟”以避免反模式中的“干预测试”,其中测试要求数据开发人员,也就是说,我需要“模拟”用户输入。这个“控制台”类就像典型的 java BufferedReader 类的一个小外观。
我把所涉及的课程传给你:
控制台:
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Console {
private BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
public String readString(String title) {
String input = null;
boolean ok = false;
do {
this.write(title);
try {
input = this.bufferedReader.readLine();
ok = true;
} catch (Exception ex) {
this.writeError("characte string");
}
} while (!ok);
return input;
}
public int readInt(String title) {
int input = 0;
boolean ok = false;
do {
try {
input = Integer.parseInt(this.readString(title));
ok = true;
} catch (Exception ex) {
this.writeError("integer");
}
} while (!ok);
return input;
}
public char readChar(String title) {
char charValue = ' ';
boolean ok = false;
do {
String input = this.readString(title);
if (input.length() != 1) {
this.writeError("character");
} else {
charValue = input.charAt(0);
ok = true;
}
} while (!ok);
return charValue;
}
public void writeln() {
System.out.println();
}
public void write(String string) {
System.out.print(string);
}
public void writeln(String string) {
System.out.println(string);
}
public void write(char character) {
System.out.print(character);
}
public void writeln(int integer) {
System.out.println(integer);
}
private void writeError(String format) {
System.out.println("FORMAT ERROR! " + "Enter a " + format + " formatted value.");
}
}
控制台测试:
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import java.io.BufferedReader;
import java.io.IOException;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.*;
import static org.mockito.MockitoAnnotations.initMocks;
public class ConsoleTest {
@Mock
private BufferedReader bufferedReader;
@InjectMocks
private Console console;
@BeforeEach
public void before(){
initMocks(this);
//this.console = new Console();
}
@Test
public void givenConsoleWhenReadStringThenValue() throws IOException {
String string = "yes";
when(this.bufferedReader.readLine()).thenReturn(string);
assertThat(this.console.readString("title"), is(string));
}
}
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<modules>
</modules>
<artifactId>solution.java.swing.socket.sql</artifactId>
<groupId>usantatecla.tictactoe</groupId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>${project.groupId}.${project.artifactId}</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.6.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>3.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>3.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>2.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.3</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>default-report</id>
<phase>post-integration-test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
<version>1.2.0</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.22.2</version>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
<version>1.2.0</version>
</dependency>
</dependencies>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
感谢社区的问候!
【问题讨论】:
-
您好,但是为什么在
before()方法中需要它this.console = new Console();? -
我认为没有必要,但如果我评论那一行,它无论如何都会出错
-
存在一些基本问题。您不能通过 new 模拟您在 sut 中创建的对象。你可以注入它,或者你可以使用工厂来创建它,然后模拟工厂。而且我看不到您是如何创建控制台的。
-
我尝试了您的代码,它与注释
this.console = new Console();并添加了junit-vintage-engine库一起使用。 -
我试过你的代码,它在简单的 spring-boot 项目版本
2.4.1中工作。我也使用了@ExtendWith(MockitoExtension.class)而不是你的@BeforeEach方法。
标签: java unit-testing mockito junit5