Mocking:验证是否调用了 Static Void 方法

问题描述 投票:0回答:0

我在处理方法的测试用例时遇到问题: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 没有被验证,但没有被调用的地方。代码的第 18 行指向在 SetUp() 中创建的 PreferenceService。从调试来看,在运行 testDeleteOldBermudaFolder() 并显示它是正确的之后,它会运行 testIsExistingDirectory() 并且当它尝试模拟 PreferenceService 时它也无法运行并声称它为空。 每当 testIsExistingDirectory() 测试被取消注释时,testIsExistingDirectory() 测试总是在它之后运行。我不确定为什么。

即使 testIsExistingDirectory() 测试失败并显示错误我不认为测试不正确。 我相信这个问题与 testDeleteOldBermudaFolder() 有关,因为它是唯一导致 testIsExistingDirectory() 出现问题的测试。而且它是唯一一个带有验证的。

在我的主要代码中,我调用了 FileUtils.deleteDirectory,这是一个静态无效方法。

我已经开始研究 PowerMockito,但我看到的每个示例都显示了一个返回值并使用 when/do 语法的方法。为此,如果该目录存在,那么我需要验证将调用 FileUtils.deleteDirectory。我需要验证声明。

我正在寻找为什么这个特定的模拟不起作用的解释?我正在寻找一个关于如何正确模拟 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 上看到了这个并尝试了一下。但是语法不正确。它也无助于验证删除的目录是否被调用。

java groovy mocking mockito powermockito
© www.soinside.com 2019 - 2024. All rights reserved.