我试图在gitlab中运行一个单元测试,测试在我的本地环境中运行正常,但是我在Gitlab中遇到了下面的错误.

我猜gitlab没有访问数据库的权限,这就是脚本无法将文件保存到数据库的原因.

以下是我在Gitlab中收到的错误信息

Error message:
[ERROR] Failures: 
[ERROR]   年度退货服务Test.testSave:102 
Wanted but not invoked:
annualReturnRepository.save(
    <any com.riskanalysisexpertsystem.scanpro.model.company.AnnualReturn>
);
-> at com.test.unit.年度退货服务Test.testSave(年度退货服务Test.java:102)
Actually, there were zero interactions with this mock.

下面是年度退货服务Test.testSave的脚本

public class 年度退货服务Test{
    
    private Logger logger;
    private PDFtoImageConverterUtility pdftoImageConverterUtility;
    private final String SOURCE_FILE_PATH = "../scanpro/src/test/resources/files/taxdocuments/company/annual_return_form.pdf";
    private final String SOURCE_DESTINATION_PATH = "../scanpro/src/test/resources/files/taxdocuments/company/annual_return.png";
    
    @Mock
    private AnnualReturnRepository annualReturnRepository;
    
    @Mock
    private OcrUtility ocrUtility;
    
    @InjectMocks
    private 年度退货服务 annualReturnService;
    
    @BeforeClass
    public void setUpBeforeClass() throws Exception{
        logger = LogManager.getLogger(年度退货服务Test.class);
        pdftoImageConverterUtility = new PDFtoImageConverterUtility();
        MockitoAnnotations.openMocks(this);
    }

    public void testSave() {
        logger.info("Mock file and file details");
        
        pdftoImageConverterUtility.convertFile(SOURCE_FILE_PATH, SOURCE_DESTINATION_PATH);
        File file = new File(SOURCE_DESTINATION_PATH);
        String fileDetails = "Annual Return Form\n"
                + "Company Name: Apple Inc.\n"
                + "\n"
                + "TIN: 3243243\n"
                + "\n"
                + "Company Address: 32432 MaryDale Drive., Ghana 234324\n"
                + "Company Registration Number: 432432\n"
                + "Fiscal Year Start Date: 2022-01\n"
                + "\n"
                + "Fiscal Year End Date: 2022-12\n"
                + "\n"
                + "Total Revenue: 342432\n"
                + "\n"
                + "Total Expenses: 3434\n"
                + "\n"
                + "Taxable Income: 34333\n"
                + "\n"
                + "Tax Paid: 3243";
        
        logger.info("Mock the behaviour of OCR utility");
        when(ocrUtility.performOCR(file)).thenReturn(fileDetails);
        
        logger.info("Call the save method");
        annualReturnService.save(file);
        
        logger.info("Verify that parseAnnualReturnDetails is not null");
        try {
            assertNotNull(annualReturnService.parseAnnualReturnDetails(fileDetails));
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        logger.info("Verify the annualReturnRepository's save method is called");
        verify(annualReturnRepository, times(1)).save(any(AnnualReturn.class));
    }
}

年度退货服务

@Service
@RequiredArgsConstructor
public class 年度退货服务 {
    
    private final AnnualReturnRepository annualReturnRepository;

    public void save(File file) {
        
        OcrUtility ocrUtility = new OcrUtility();
        String fileDetails = ocrUtility.performOCR(file);
        
        if (fileDetails != null) {
            
            AnnualReturn annualReturn = new AnnualReturn();
            try {
                annualReturn = parseAnnualReturnDetails(fileDetails);
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            if (annualReturn != null) {
                annualReturnRepository.save(annualReturn);
            }
        }
    }

快走,快走!

test:
  stage: test
  script:
    - mvn test -Dtest=com.test.unit.年度退货服务Test
  allow_failure: true
  dependencies:
    - build
  artifacts:
    paths: 
      - target/surefire-reports
    expire_in: "30 days"

推荐答案

gitlab的错误看起来像一个Mockito验证错误,与数据库访问无关.

这有两个明显的原因.

  1. 在被测试的服务中有一个逻辑,当给定测试模拟条件时,它可以避免annualReturnRepository.Save()调用.
  2. 您的模拟没有正确地注入到服务中.

也许您可以提供测试定义和一些来自被测服务的代码.

PS如果你只想验证一个方法调用,可以跳过times(1)

verify(annualReturnRepository).save(any(AnnualReturn.class));

After author added test definitions

从测试来看,这似乎很不合适

assertNotNull(annualReturnService.parseAnnualReturnDetails(fileDetails));

您应该只从被测试的服务调用单个方法.也

any(AnnualReturn.class) // also checks for null

我认为parseAnnualReturnDetails中发生的任何事情,当你从测试中调用它时都会返回一些非空结果,但当它从实际的测试服务中调用时,它会返回一个null AnnualReturn,避免了repo调用并触发了Mockito验证错误.

Java相关问答推荐

JUnit—如何模拟局部变量对象方法调用

在JavaFX项目中注册组合框的控件FX验证器时,模块系统出错

Spring Boot Maven包

如何解释Java中for-each循环中对Iterable的强制转换方法引用?

如何从日志(log)行中删除包名称?

如何在 spring 数据的MongoDB派生查询方法中使用$EXISTS

buildDir:File!&#的getter解决方案是什么?39.被抛弃

如何获得凌空cookies ,并设置它在下一个请求- android

在JDK Flight Recorder中只记录单个线程

Java KeyListener不工作或被添加

为什么创建Java动态代理需要接口参数

不能在 map 上移除折线

Kotlin-仅替换字符串中最后一个给定的字符串

具有多个分析模式的复杂分隔字符串的正则表达式

在Spring Boot中使用咖啡因进行缓存

设置背景时缺少Android编辑文本下划线

为什么我得到默认方法的值而不是被覆盖的方法的值?

java中的网上购物车解析错误

如何使用java区分以下结果

Spring Boot应用程序中的自定义constraintvalidator不会被调用