为什么我在这里得到 UnfinishedStubbingException?
Why do I get UnfinishedStubbingException here?
测试代码为:
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.time.LocalTime;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
public class HelloWorldByHour {
private static LocalTime REST_START_TIME = LocalTime.of(14, 0);
private static LocalTime REST_END_TIME = LocalTime.of(16, 0);
public static void main(String[] args) throws Exception {
HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
server.createContext("/greeting", new MyHandler());
server.setExecutor(null); // creates a default executor
server.start();
}
private static class MyHandler implements HttpHandler {
public void handle(HttpExchange t) throws IOException {
LocalTime time = LocalTime.now();
String response;
if (time.isAfter(REST_START_TIME) && time.isBefore(REST_END_TIME)) {
response = "Nap time";
} else {
response = "Hello World";
}
t.sendResponseHeaders(200, response.length());
OutputStream os = t.getResponseBody();
os.write(response.getBytes());
os.close();
}
}
}
当运行我得到的测试:
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at HelloWorldByHourTest.testMain(HelloWorldByHourTest.java:35)
E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, you naughty developer!
3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed
我的pom.xml是
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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>
<groupId>server</groupId>
<artifactId>server</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>(whatever version is current)</version>
<configuration>
<!-- or whatever version you use -->
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-core</artifactId>
<version>1.6.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.6.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
</dependencies>
</project>
测试代码为:
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.time.LocalTime;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.when;
@RunWith(PowerMockRunner.class)
@PrepareForTest(LocalTime.class)
public class HelloWorldByHourTest {
private String sendRequest() throws IOException {
URL url = new URL("localhost:8080/greeting");
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
String strTemp = "";
StringBuilder sb = new StringBuilder();
while (null != (strTemp = br.readLine())) {
sb.append(strTemp);
}
return sb.toString();
}
@Test
public void testMain() throws Exception {
mockStatic(LocalTime.class);
when(LocalTime.now()).thenReturn(LocalTime.of(15, 0));
HelloWorldByHour.main(null);
String response = sendRequest();
Assert.assertEquals("Nap time", response);
}
}
知道哪里出了问题吗?
问题是您在 when
和 thenReturn
中对 LocalDate 调用了静态方法
尝试这样的事情:
LocalTime time = LocalTime.of(15,0);
mockStatic(LocalTime.class);
when(LocalTime.now()).thenReturn(time);
通过此电话 when(LocalTime.now()).thenReturn(LocalTime.of(15, 0));
您比较适合:
3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed.
基本上你已经静态地模拟了 LocalTime
class 但你也在调用静态 LocalTime.of(15, 0)
方法同时定义 LocalTime.now()
.
根据你想做什么,我想一个解决方法是在模拟静态方法之前创建一个 LocalTime
的模拟,类似于:
@Test
public void testMain() throws Exception {
// create a mock
LocalTime mockLocalTime = mock(LocalTime.class);
// TODO define behaviour of mockLocalTime
// mock the static methods
mockStatic(LocalTime.class);
when(LocalTime.now()).thenReturn(mockLocalTime);
// invoke object under test
HelloWorldByHour.main(null);
String response = sendRequest();
// interaction verification and/or assersions
Assert.assertEquals("Nap time", response);
}
测试代码为:
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.time.LocalTime;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
public class HelloWorldByHour {
private static LocalTime REST_START_TIME = LocalTime.of(14, 0);
private static LocalTime REST_END_TIME = LocalTime.of(16, 0);
public static void main(String[] args) throws Exception {
HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
server.createContext("/greeting", new MyHandler());
server.setExecutor(null); // creates a default executor
server.start();
}
private static class MyHandler implements HttpHandler {
public void handle(HttpExchange t) throws IOException {
LocalTime time = LocalTime.now();
String response;
if (time.isAfter(REST_START_TIME) && time.isBefore(REST_END_TIME)) {
response = "Nap time";
} else {
response = "Hello World";
}
t.sendResponseHeaders(200, response.length());
OutputStream os = t.getResponseBody();
os.write(response.getBytes());
os.close();
}
}
}
当运行我得到的测试:
org.mockito.exceptions.misusing.UnfinishedStubbingException: Unfinished stubbing detected here: -> at HelloWorldByHourTest.testMain(HelloWorldByHourTest.java:35)
E.g. thenReturn() may be missing. Examples of correct stubbing: when(mock.isOk()).thenReturn(true); when(mock.isOk()).thenThrow(exception); doThrow(exception).when(mock).someVoidMethod(); Hints: 1. missing thenReturn() 2. you are trying to stub a final method, you naughty developer! 3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed
我的pom.xml是
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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>
<groupId>server</groupId>
<artifactId>server</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>(whatever version is current)</version>
<configuration>
<!-- or whatever version you use -->
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-core</artifactId>
<version>1.6.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.6.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
</dependencies>
</project>
测试代码为:
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.time.LocalTime;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.when;
@RunWith(PowerMockRunner.class)
@PrepareForTest(LocalTime.class)
public class HelloWorldByHourTest {
private String sendRequest() throws IOException {
URL url = new URL("localhost:8080/greeting");
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
String strTemp = "";
StringBuilder sb = new StringBuilder();
while (null != (strTemp = br.readLine())) {
sb.append(strTemp);
}
return sb.toString();
}
@Test
public void testMain() throws Exception {
mockStatic(LocalTime.class);
when(LocalTime.now()).thenReturn(LocalTime.of(15, 0));
HelloWorldByHour.main(null);
String response = sendRequest();
Assert.assertEquals("Nap time", response);
}
}
知道哪里出了问题吗?
问题是您在 when
和 thenReturn
尝试这样的事情:
LocalTime time = LocalTime.of(15,0);
mockStatic(LocalTime.class);
when(LocalTime.now()).thenReturn(time);
通过此电话 when(LocalTime.now()).thenReturn(LocalTime.of(15, 0));
您比较适合:
3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed.
基本上你已经静态地模拟了 LocalTime
class 但你也在调用静态 LocalTime.of(15, 0)
方法同时定义 LocalTime.now()
.
根据你想做什么,我想一个解决方法是在模拟静态方法之前创建一个 LocalTime
的模拟,类似于:
@Test
public void testMain() throws Exception {
// create a mock
LocalTime mockLocalTime = mock(LocalTime.class);
// TODO define behaviour of mockLocalTime
// mock the static methods
mockStatic(LocalTime.class);
when(LocalTime.now()).thenReturn(mockLocalTime);
// invoke object under test
HelloWorldByHour.main(null);
String response = sendRequest();
// interaction verification and/or assersions
Assert.assertEquals("Nap time", response);
}