groovy 模拟:验证是否调用了静态Void方法

w8f9ii69  于 2023-04-19  发布在  其他
关注(0)|答案(1)|浏览(136)

我在方法的测试用例方面遇到了问题:deleteOldBermudaFolder和isExistingDirectory,代码如下:

class BermudaCacheDumpServiceImpl implements BermudaCacheDumpService {

    @Autowired
    PreferenceService preferenceService

    @Autowired
    FileUtils fileUtils

    static final String WORKING_DIR = 'bermudaCacheDumpWorkDir'
    static final String FOLDER_TO_DELETE = 'bermudaCacheDumpDeleteFolder'

    boolean isLandingStripAssembled(){
        boolean isLSAssembled
        File oldBermudaFolder = new File(workingDirectory + folderToDelete)

        deleteOldBermudaFolder(oldBermudaFolder)

        isLSAssembled = hasValidFiles()
        isLSAssembled
    }

    void deleteOldBermudaFolder(File oldBermudaFolder) throws IOException{
        if(isExistingDirectory(oldBermudaFolder)){
            fileUtils.deleteDirectory(oldBermudaFolder)
        }
        else{
            log.error("Unable to delete directory")
        }
    }

    boolean isExistingDirectory(File file){
        file.exists() && file.isDirectory()
    }

    boolean isExistingFile(File file){
        file.exists() && file.isFile()
    }

    private String getWorkingDirectory(){    preferenceService.getValue(WORKING_DIR)    }

    private String getFolderToDelete(){    preferenceService.getValue(FOLDER_TO_DELETE)    }

我的测试案例:

class BermudaCacheDumpServiceImplTest extends GroovyTestCase{

    BermudaCacheDumpServiceImpl bermudaCacheDumpService
    PreferenceService mockPreferenceService
    FileUtils mockFileUtils

    void setUp(){
        mockPreferenceService = mock(PreferenceService) //Line 18
        mockFileUtils = mock(FileUtils)
        bermudaCacheDumpService = new BermudaCacheDumpServiceImpl(preferenceService: mockPreferenceService, fileUtils: mockFileUtils)
    }

    void testIsExistingFile()
    {
        File mockedFile = mock(File.class)
        when(mockedFile.exists()).thenReturn(true)
        when(mockedFile.isFile()).thenReturn(true)

        assert bermudaCacheDumpService.isExistingFile(mockedFile)
    }

    void testIsExistingDirectory(){
        File mockedFile = mock(File.class)
        when(mockedFile.exists()).thenReturn(true)
        when(mockedFile.isDirectory()).thenReturn(true)

        assert bermudaCacheDumpService.isExistingDirectory(mockedFile)
    }

    void testDeleteOldBermudaFolder(){
        def dummyFile = new File("/apps/Codes/PLS/LS/bermuda")
        File mockedFile = mock(File.class)

        when(bermudaCacheDumpService.isExistingDirectory(mockedFile)).thenReturn(true)
        bermudaCacheDumpService.deleteOldBermudaFolder(mockedFile)
        verify(bermudaCacheDumpService.fileUtils, times(1)).deleteDirectory(dummyFile)
    }
}

问题:当我注解掉testDeleteOldBermudaFolder()时,整个测试文件运行没有错误。但是当我取消注解testDeleteOldBermudaFolder()时,我在testIsExistingDirectory()上得到一个错误。
单独运行时,所有测试都没有错误,并显示为通过,但当作为一个单元运行时,testDeleteOldBermudaFolder()未注解,testIsExistingDirectory()测试失败。

org.mockito.exceptions.misusing.UnfinishedVerificationException: 
Missing method call for verify(mock) here:
-> at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallStatic(CallSiteArray.java:53)
Example of correct verification:
    verify(mock).doSomething()

Also, this error might show up because you verify either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
Mocking methods declared on non-public parent classes is not supported.

at com.thomsonreuters.legal.lpa.bermudacachedump.BermudaCacheDumpServiceImplTest.setUp(BermudaCacheDumpServiceImplTest.groovy:18)

从上面的错误中可以看出,CallSiteArray没有被验证,但是没有被调用的位置。().从调试运行testDeleteOldBermudaFolder后()并显示它是正确的,它将运行testIsExistingDirectory当它试图模拟PreferenceService时,它也无法模拟,并声称它为null。()测试是未注解的,testIsExistingDirectory()测试总是在它之后运行。我不知道为什么。
即使testIsExistingDirectory()测试失败并显示错误,我不相信该测试是不正确的。我相信这个问题与testDeleteOldBermudaFolder()有关,因为它是导致testIsExistingDirectory()出现问题的唯一测试。并且它是唯一一个包含验证的测试。
在我的主代码中,我调用FileUtils.deleteDirectory,这是一个静态void方法。
我已经开始研究PowerMockito,但我看到的每个例子都显示了一个返回值并使用when/do语法的方法。为此,如果目录存在,那么我需要验证FileUtils。deleteDirectory将被调用。我需要那个verify语句。

**我正在寻找一个解释,为什么这个特定的模拟不起作用?我正在寻找一个关于如何正确模拟FileUtils的例子。deleteDirectory来验证它正在被调用。**特别是语法。或者寻找一个解决方案来验证FileUtils。

verify(fileUtils, times(1)).deleteDirectory(new File("/apps/Codes/PLS/LS/bermuda"))

与上述错误相同

verify(FileUtils, times(1)).deleteDirectory(dummyFile)

与上述错误相同

verify(bermudaCacheDumpService.fileUtils).deleteDirectory(dummyFile)

与上述错误相同

FileUtils fileUtils = mock(FileUtils.class)
verify(fileUtils, times(1)).deleteDirectory(dummyFile)

与上述错误相同

PowerMockito.verifyStatic(bermudaCacheDumpService.fileUtils, times(1)).deleteDirectory(dummyFile)

语法不正确- PowerMockito无法应用于FileUtils

PowerMockito.verifyStatic(FileUtils.class, times(1))

语法不正确- PowerMockito无法应用于FileUtils

PowerMockito.mockStatic(FileUtils.class, { invocationOnMock ->
    assertEquals(dummyFile, invocationOnMock.getArgument(0, File.class))
    return null
})

我在StackOverflow上看到了这个,并尝试了一下。但是语法不正确。它也不能帮助验证deletedirectory是否被调用。

cdmah0mi

cdmah0mi1#

我可以推荐你使用mockito-inline来模拟静态方法,如下所示:

try (MockedStatic<FileUtils> MockedStatic = mockStatic(FileUtils.class)) {

    MockedStatic
        .verify(() -> FileUtils.deleteDirectory(dummyFile), times(1));
}

这里有一些例子-〉mocking static methods

相关问题