简体   繁体   English

Mockito.doThrow() 不抛出任何异常

[英]Mockito.doThrow() not throwing any exception

I am trying to stub a void method of a mocked object to return an exception.我正在尝试对模拟的 object 的 void 方法进行存根以返回异常。 This mocked object passed as dependency to the service which I am writing tests for.这个模拟的 object 作为依赖项传递给我正在为其编写测试的服务。

Service:服务:

@Component
public class FileHandler {

    private static final Logger log = LoggerFactory.getLogger(FileHandler.class);

    private final SSHAccess sshAccess;
    @Value("${datastore.location}")
    private String dataStoreDir;

    public FileHandler(SSHAccess sshAccess){
        this.sshAccess = sshAccess;
    }

    public Either<Pair<Exception, FileRecord>, FileRecord> transferFile(FileRecord fileRecord){
        try {
            var sourceURI = new URI(fileRecord.getSourceURI());
            var digest = sshAccess.execute("md5sum " + sourceURI.getPath())
                    .replaceFirst("([^\\s]+)[\\d\\D]*", "$1");
            if (digest.equals(fileRecord.getSourceDigest())) {
                log.info(Thread.currentThread().getName() + ": Copying file: " + fileRecord.getId() + " of submission: " + fileRecord.getOwnedBy());
                sshAccess.download(sourceURI.getPath(),new File(mkdir(dataStoreDir, digest), digest));
                log.info(Thread.currentThread().getName() + ": Copying of file: " + fileRecord.getId() + " of submission: " + fileRecord.getOwnedBy() + " finished.");
                return Either.Right(fileRecord);
            }else{
                log.error("MD5 mismatch for source file {}", sourceURI.getPath());
                return Either.Left(Pair.of(new FileHandlerException("MD5 mismatch"), fileRecord));
            }

        } catch (URISyntaxException
                | IOException
                e) {
            return Either.Left(Pair.of(new FileHandlerException(e), fileRecord));
        }
    }

    private File mkdir(String dataStoreDir, String digest) throws IOException {
        File dir = new File(dataStoreDir, digest.substring(0, 3));
            if (!dir.exists() && !dir.mkdirs()) {
                log.error("Unable to create directory {}", dir);
                throw new IOException("Unable to create directory " + dir);
            }
        return dir;
    }
}

Test Class:测试 Class:

@SpringBootTest
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class FileHandlerTest {
    private FileHandler fileHandler;

    @Mock
    private SSHAccess sshAccess;

    @BeforeAll
    public void init(){
       fileHandler = Mockito.spy(new FileHandler(sshAccess));
     
    }

        
    @Test
    public void transferFileShouldReturnFileHandlerExceptionOnEitherLeftWhenSSHclientThrowsIOException() throws IOException {
        FileRecord fileRecord = getFileRecord();
        var digest = "6e484ac23110fae10021e";
        when(sshAccess.execute(anyString())).thenReturn(digest);
        doThrow(IOException.class).when(sshAccess).download(anyString(), any(File.class));
        var result = fileHandler.transferFile(fileRecord);
        Assertions.assertTrue(result.getLeft().isPresent()
                && result.getLeft().get().getFirst() instanceof FileHandlerException);
    }

    private FileRecord getFileRecord() {
        var fileRecord = new FileRecord();
        fileRecord.setId(1L);
        fileRecord.setOwnedBy(1000);
        fileRecord.setSourceURI("scp:host/test/uri/filename");
        fileRecord.setSourceDigest("6e484ac23110fae10021e");
        return fileRecord;
    }
}

But when I run this test case, doThrow() doesn't throw any exception.但是当我运行这个测试用例时, doThrow() 不会抛出任何异常。 Method executed without any exception and test failed.方法执行没有任何异常并且测试失败。 I am not sure what I am doing wrong here.我不确定我在这里做错了什么。 Please help.请帮忙。

Not sure why are you using the @SpringBootTest annotation which will try to raise a similar context with the one when you are running the app.不确定您为什么要使用 @SpringBootTest 注释,它会在您运行应用程序时尝试引发与该注释类似的上下文。 So in this case you could stop instantiating your FileHandler and just spy on it and on your SSHAccess beans or use @MockBean instead of @Mock.所以在这种情况下,你可以停止实例化你的 FileHandler,只监视它和你的 SSHAccess bean,或者使用@MockBean 而不是@Mock。

Basically you should have something like this基本上你应该有这样的东西

@SpyBean
private FileHandler fileHandler;

@MockBean
private SSHAccess sshAccess;

You are using Junit 5 .您正在使用Junit 5 For Junit 5 you don't need the method @SpringBootTest , you need to use @ExtendWith(MockitoExtension.class)对于 Junit 5 你不需要方法@SpringBootTest ,你需要使用@ExtendWith(MockitoExtension.class)

@SpringBootTest
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class FileHandlerTest {
    private FileHandler fileHandler;

    @Mock
    private SSHAccess sshAccess;

    @BeforeAll
    public void init(){
       fileHandler = Mockito.spy(new FileHandler(sshAccess));
     
    }
.....
.....
.....
}

Also instead of Mockito.spy(new FileHandler(sshAccess)) you can try Mockito.mock(new FileHandler(sshAccess))也可以代替Mockito.spy(new FileHandler(sshAccess))您可以尝试Mockito.mock(new FileHandler(sshAccess))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM