使用TemporaryFolder

时间:2016-06-16 23:42:30

标签: java junit access-denied

我遇到了JUnit测试的问题。如果传递的InputStream不支持标记/重置,则我测试的方法需要一个InputStream抛出异常。

我遇到的问题是,当一个不支持标记/重置的InputStream被传递(在下面发布)时,我的测试确保异常被抛出。持续抛出一个AccessDeniedException。

public class IOTest{

@Rule
public TemporaryFolder tempFolder = TemporaryFolder()

@Before
public void createFolder() throws IOException {
Files.createDirectories(tempFolder.getRoot().toPath().resolve("testFile"));
}

@Test(expected = IllegalArgumentException.class)
public void testDetectCharsetOnlyAcceptsMarkResetSupportedInputStreams() throws IOException {
final Path testPath = tempFolder.getRoot().toPath().resolve("testFile");
final InputStream testStream = Files.newInputStream(testPath);
IO.detectCharset(testStream);
}
}

我认为我遇到的问题与访问临时文件夹有关,但我不知道如何规避这个问题。

以下是运行此测试时打印的堆栈跟踪:

java.lang.Exception: Unexpected exception, expected<java.lang.IllegalArgumentException> but was<java.nio.file.AccessDeniedException>
    at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:28)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
    at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Caused by: java.nio.file.AccessDeniedException: C:\Users\antho\AppData\Local\Temp\junit4390480127201295432\testFile
    at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:83)
    at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
    at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
    at sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:230)
    at java.nio.file.Files.newByteChannel(Files.java:361)
    at java.nio.file.Files.newByteChannel(Files.java:407)
    at java.nio.file.spi.FileSystemProvider.newInputStream(FileSystemProvider.java:384)
    at java.nio.file.Files.newInputStream(Files.java:152)
    at com.bunnell.anthony.booker.IOTest.testDetectCharsetOnlyAcceptsMarkResetSupportedInputStreams(IOTest.java:65)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:19)
    ... 24 more

我猜它与权限和操作系统有关,但我不知道如何解决这个问题。如果有帮助,我使用的是Windows 10。

感谢先进的任何想法,意见和帮助。

2 个答案:

答案 0 :(得分:0)

你试图从testFile读取,它不是文件而是目录;你是用

创建的
Files.createDirectories(tempFolder.getRoot().toPath().resolve("testFile"));

documentation说:

  

首先通过创建所有不存在的父目录来创建目录

(强调我的)

答案 1 :(得分:0)

为了保持JUnit测试的可移植性和简单性,我建议完全删除外部文件依赖项。

您可以通过两种方式执行此操作:

  1. 从内部创建一个InputStream,如String或byte数组。 Here is how with strings

  2. 使用模拟框架(例如Mockito)创建一个虚拟InputStream,它具有足够的功能来确认方法是否有效。这将是我的首选策略,因为模拟会产生更清晰的测试。