Java 模拟单例的getInstance()以返回子类(Quarkus)
我试图模拟下面一个单例类的getInstance(),以返回模拟的类:Java 模拟单例的getInstance()以返回子类(Quarkus),java,unit-testing,mockito,singleton,quarkus,Java,Unit Testing,Mockito,Singleton,Quarkus,我试图模拟下面一个单例类的getInstance(),以返回模拟的类: 基类(passo9()是要模拟的方法): 包br.com.bb.ids.robo.passo09; 导入br.com.bb.ids.robo.passo09.dao.RoboSkipDao; 导入br.com.bb.ids.robo.passo09.exceptions.RoboSkipDaoFindException; 导入br.com.bb.ids.robo.passo09.exceptions.RoboSkipDaoM
包br.com.bb.ids.robo.passo09;
导入br.com.bb.ids.robo.passo09.dao.RoboSkipDao;
导入br.com.bb.ids.robo.passo09.exceptions.RoboSkipDaoFindException;
导入br.com.bb.ids.robo.passo09.exceptions.RoboSkipDaoMergeException;
导入br.com.bb.ids.robo.passo09.models.RoboSkip;
导入javax.enterprise.context.ApplicationScoped;
@适用范围
公共级电动机{
私人静电马达实例;
公共静态马达getInstance(){
if(实例==null){
实例=新电机();
}
返回实例;
}
私家车(){}
/**
*要模拟的方法
*
*@返回错误代码(如果成功,则为0)
*@Exception抛出任何非预期的异常
*/
public int passo9()引发异常{
试一试{
系统输出打印(Verifica o ponto onde o robôparou);
RoboSkipDao rsDao=RoboSkipDao.getInstance();
RoboSkip rs=rsDao.findByPasso(9);
int resultadoPasso=Integer.parseInt(rs.getValor());
rs.setValor(Integer.toString(resultadoPasso+32768));
合并(rs);
}
渔获物(Roboskipdaofindexe){
System.out.println(“Erro ao consultar registro em robo_skip,passo=9”);
e、 printStackTrace();
返回2;
}
捕获(数字格式){
System.out.println(“Número do registro inválido em robo_skip,passo 9”);
e、 printStackTrace();
返回3;
}
捕获(Roboskipdaoe){
System.out.println(“Erro ao atualizar registro em robo_skip,passo 9”);
e、 printStackTrace();
返回8;
}
返回0;
}
}
包br.com.bb.ids.robo.passo09;
导入io.quarkus.test.Mock;
导入javax.enterprise.context.ApplicationScoped;
@嘲弄
@适用范围
公共级摩托车{
公共摩托摩克(摩托m){}
@凌驾
public int passo9()引发异常{
System.out.println(“passo9()mockado-返回0”);
返回0;
}
}
包br.com.bb.ids.robo.passo09;
导入io.quarkus.runtime.quarkus;
导入io.quarkus.runtime.annotations.QuarkusMain;
@夸克斯曼
公共班机{
公共静态void main(字符串[]args){
如果(args.length!=1 | |!args[0]。匹配(“true | false”)){
系统错误println(“Indicação em desenvolvimento(真/假)obrigatória”);
返回;
}
布尔值emDesenvolvimento=boolean.parseBoolean(args[0]);
System.out.println(“Iniciando aplicação…”);
试一试{
Motor=Motor.getInstance();
电机。setEmDesenvolvimento(emDesenvolvimento);
int returnCode=motor.passo9();
System.out.println(“Finalizando aplicação…”);
Quarkus.asyncExit(返回代码);
}
捕获(例外e){
e、 printStackTrace();
}
}
}
包br.com.bb.ids.robo.passo09;
导入io.quarkus.test.junit.QuarkusMock;
导入io.quarkus.test.junit.QuarkusTest;
导入javax.inject.inject;
导入org.junit.jupiter.api.Test;
@夸克斯特
公共类测试{
@注入
电机;
@试验
公共void testMain(){
MotorMock mm=新的MotorMock(Motor.getInstance());
Mockito.when((Motor)mm.getInstance()),然后返回(mm);
QuarkusMock.installMockForType(mm,电机类);
System.out.println(“Testando Main.Main(args)…”;
字符串[]args=新字符串[1];
args[0]=“真”;
Main.Main(args);
System.out.println(“Testes com Main.Main(args)efetuados com successo”);
}
}
我想在测试用例中调用MotorMock.passo9(),而不是Motor.passo9()。我如何做到这一点?如果可能,请与代码示例共享。您不应使用
@Mock
或@ApplicationScoped
注释MotorMock
。您可以删除它们并重试吗?首先,去掉getInstance()
方法。永远不要以编程方式实例化应该由CDI容器管理的类。相反,可以使用@Inject
,或者如果确实需要,可以使用CDI.current()
。然后,QuarkusMock.installMockForType
应该可以工作。@Ladicek我真的必须在这个类上使用getInstance()
(无法摆脱它)。如果可能的话,我希望看到CDI.current()
的编码示例以及QuarkusMock.installMockForType
。我100%确信可以摆脱手动实例化该类。最坏的情况是getInstance
方法如下:返回CDI.current().select(Motor.class).get()
。然而,在绝大多数情况下,您可以摆脱这种情况,使用@Inject
、producer方法等。要点是:您将类声明为bean(@ApplicationScoped
),因此您应该让CDI容器管理其生命周期(这也是模拟可以实际工作的原因),并且永远不要手动实例化它。