我有两个单身班
public class Singleton1 {
private static Singleton1 INSTANCE = null;
private final Singleton2 singleton2;
private Singleton1(Singleton2 singleton2){
this.singleton2 = singleton2;
}
public static Singleton1 getInstance(Singleton2 singleton2) {
if(INSTANCE == null) {
synchronized (Singleton1.class) {
INSTANCE = new Singleton1(singleton2);
}
}
return INSTANCE;
}
public String getOutput(String input) {
switch(input) {
case "CONNECT" : return "Connected";
case "PING" : return singleton2.getPingResponse(input);
default: return "nevermind";
}
}
}
单人二等舱
public class Singleton2 {
private static Singleton2 INSTANCE = null;
private Singleton2(){
}
public static Singleton2 getInstance() {
if(INSTANCE == null) {
synchronized (Singleton1.class) {
INSTANCE = new Singleton2();
}
}
return INSTANCE;
}
public String getPingResponse(String s) {
System.out.println("CALLING HERE");
if(s.contains("CON")) {
return "connected";
} else {
return "OK";
}
}
}
测试类别
@ExtendWith(MockitoExtension.class)
@RunWith(JUnitPlatform.class)
public class Singleton1Test { // if running all tests together then the mocking is not happening
Singleton2 s2 = Mockito.mock(Singleton2.class);
// Singleton2 s2 = Mockito.mock(Singleton2.class);
// Singleton2 spiedS2 = Mockito.spy(s2); // if I use spying it will call real method
Singleton1 s1 = Singleton1.getInstance(s2);
@Test // this test alone is fine
public void TestConnect() {
Assertions.assertEquals("Connected", s1.getOutput("CONNECT"));
}
@Test // this test alone is fine
public void TestPing() {
// mock will work when I run this test alone
Mockito.doReturn("OK").when(s2).getPingResponse(anyString());
// this is calling real method from singleton2 object
// Mockito.doReturn("OK").when(spiedS2).getPingResponse(anyString());
Assertions.assertEquals("OK", s1.getOutput("PING"));
}
}
如何为singleton1类执行适当的JUNIT,我不想在运行singleton1时从Singleton2执行任何方法。我试着刺探和嘲弄。当我在监视时,真正的方法是被调用。当我模拟Singleton2时,由于模拟调用问题,所有测试运行都失败了。
如果我错了,请告诉我
经过几次搜索后,我通过两个注释修复了它。现在,我可以一起运行所有测试而不会出错。我将S2重命名为真实S1的属性名称。因此@InjectMock将毫无歧义地工作。大多数情况下,@InjectMock将通过setter或构造函数注入工作。这里我的构造函数是私有的,但它对我有用。
@ExtendWith(MockitoExtension.class)
class SingletonTest {
@Mock
Singleton2 singleton2;
@InjectMocks
Singleton1 s1;
@Test // this test alone is fine
public void TestConnect() {
Assertions.assertEquals("Connected", s1.getOutput("CONNECT"));
}
@Test // this test alone is fine
void ping() {
Mockito.doReturn("OK").when(singleton2).getPingResponse(anyString());
Assertions.assertEquals("OK", s1.getOutput("PING"));
}
}
Spy正在处理实例。
Singleton2 s2 = Singleton2.getInstance();
Mock不需要任何Singleton2实例来模拟它。
我取了你的代码,稍微修改了一下测试(小写的start方法名称,将anyString()更改为ArgumentMatchers.any(String.class))并对其进行了测试。对我来说,它工作正常。我使用的是Junit5.7.1和Mockito 3.8.0。由于测试ping方法对您来说失败了,我没有在我的示例中插入测试连接。
我认为您的错误是混淆了Mock和Spy,而没有使用Singleton2的实例。让我向您展示。
我使用以下导入的示例
import static org.mockito.ArgumentMatchers.any;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
您的代码使用Mock和Spy Singleton2(我根据您的注释进行假设)
@ExtendWith(MockitoExtension.class)
class SingletonTest {
// Singleton2 s2 = Singleton2.getInstance();
Singleton2 s2 = Mockito.mock(Singleton2.class);
Singleton2 spiedS2 = Mockito.spy(s2); // if I use spying it will call real method
Singleton1 s1 = Singleton1.getInstance(s2);
@Test // this test alone is fine
void ping() {
// mock will work when I run this test alone
// Mockito.doReturn("OK").when(s2).getPingResponse(any(String.class));
// this is calling real method from singleton2 object
Mockito.doReturn("OK").when(spiedS2).getPingResponse(any(String.class));
Assertions.assertEquals("OK", s1.getOutput("PING"));
}
}
结果在
org.opentest4j.AssertionFailedError: expected: <OK> but was: <null>
at org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55)
...
仅在Singleton2上使用带有实例的间谍
@ExtendWith(MockitoExtension.class)
class SingletonTest {
Singleton2 s2 = Singleton2.getInstance();
// Singleton2 s2 = Mockito.mock(Singleton2.class);
Singleton2 spiedS2 = Mockito.spy(s2);
Singleton1 s1 = Singleton1.getInstance(spiedS2);
@Test // this test alone is fine
void ping() {
// Mockito.doReturn("OK").when(s2).getPingResponse(any(String.class));
Mockito.doReturn("OK").when(spiedS2).getPingResponse(any(String.class));
Assertions.assertEquals("OK", s1.getOutput("PING"));
}
}
顺利通过测试。如果您使用
Singleton1 s1 = Singleton1.getInstance(s2);
仅在没有实例的Singleton2上使用Mock
@ExtendWith(MockitoExtension.class)
class SingletonTest {
Singleton2 s2 = Mockito.mock(Singleton2.class);
// Singleton2 s2 = Singleton2.getInstance();
// Singleton2 spiedS2 = Mockito.spy(s2);
Singleton1 s1 = Singleton1.getInstance(s2);
@Test // this test alone is fine
void ping() {
Mockito.doReturn("OK").when(s2).getPingResponse(any(String.class));
// Mockito.doReturn("OK").when(spiedS2).getPingResponse(any(String.class));
Assertions.assertEquals("OK", s1.getOutput("PING"));
}
}
还顺利通过了测试。
根据第二个答复作出的补充
您还可以通过注释定义Mock。(我之前没有使用它们,因为示例代码没有使用它们。)
@Mock
Singleton2 singleton2;
@InjectMocks
Singleton1 s1;
我有一个测试,如下所示,在给定条件下,我想确保。 然而,它错误地指出 错误出现在行 应为不是模拟对象。如何测试为非模拟对象调用的方法? 我在如何验证一个非模拟对象的方法中看到了答案?,但这仍然是使用模拟和间谍。我希望找到一种不需要嘲笑我已经拥有的类实例的方法。 (注:以上内容以科特林书写)
我是Java初学者。我想在运行的Java线程对象中调用一个方法。它总是引发以下异常: 线程“AWT-EventQueue-0”java中出现异常。lang.NullPointerException:无法调用“Graphic\u handler.next()”,因为“this.this$0.grap”为null (代码已简化) 下面是我调用该方法的代码部分: 我试图在这里调用方法Next()和las
好的,我有一个我正在创建的小程序叫做移动电话。它有三个类:Main.java、Contact.java和MobilePhone.java. 主要的java使用扫描器执行静态方法,通过电话菜单显示和返回信息。联系java是一个简单的类,它将姓名和号码存储为联系人。手机。java有as ArrayList,它将Contact类中的对象存储为contacts,然后有几个方法,比如addContact()
我想在JUnit中创建用于测试运行的自定义html报告。我有一个问题是释放资源和关闭标记后,所有的测试都完成了。 我保留了一个打开的文件,以便编写报告。因为每个测试都应该是表和行,而且有数百个,所以我不想为每个测试打开和关闭通道。这里出现的问题是测试组织--我有嵌套的套件,所以testRunFinished不是一个选项(指单个套件,不是所有测试,我看到了这个问题)。TestWatcher也不会帮助
下面是我要为其创建测试的类和方法: 具体地说,我希望模拟getAnalytics.getAll(),这样它就会返回一个我已经定义的字符串。而不是方法执行它的任务。这是我的代码:
所以我有一个名为Tile的超类和许多子类,如BlueTile,GreenTile等。 不同子类的所有实例都存储在ArrayList中(例如(blueTile1、blueTile2、greenTile1……)。 在超类中有一个名为“activateTile()”的方法,所有子类都以不同的方式使用它。 现在,当我在阵列中循环并用blueTile激活所有蓝色Tile时。它们会一个接一个地被激活,对吗?