使用 TemporaryFolder 的 JUnit 测试中的 AccessDeniedException
AccessDeniedException in JUnit test using a TemporaryFolder
我做的 JUnit 测试有问题。如果传递的 InputStream
不支持 mark/reset.
,我正在测试的方法采用 InputStream
应该抛出异常
我 运行 遇到的问题是,当不支持 mark/reset 的 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.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.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=11=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.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.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
我猜它与权限和 OS 有关,但我不确定如何解决这个问题。如果有帮助,我正在使用 Windows 10.
您正在尝试从 testFile 中读取,它不是文件而是目录;您正在使用
创建
Files.createDirectories(tempFolder.getRoot().toPath().resolve("testFile"));
谁的 documentation 说:
Creates a directory by creating all nonexistent parent directories first.
(强调我的)
为了保持 JUnit 测试的可移植性和简单性,我建议完全删除外部文件依赖性。
您可以通过两种方式执行此操作:
从内部的东西创建一个 InputStream,比如字符串或字节数组。 Here is how with strings
使用模拟框架,例如 Mockito,创建一个虚拟 InputStream,其功能刚好足以确认该方法有效。这是我的首选策略,因为模拟会产生更清晰的测试。
我做的 JUnit 测试有问题。如果传递的 InputStream
不支持 mark/reset.
InputStream
应该抛出异常
我 运行 遇到的问题是,当不支持 mark/reset 的 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.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.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=11=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.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.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
我猜它与权限和 OS 有关,但我不确定如何解决这个问题。如果有帮助,我正在使用 Windows 10.
您正在尝试从 testFile 中读取,它不是文件而是目录;您正在使用
创建Files.createDirectories(tempFolder.getRoot().toPath().resolve("testFile"));
谁的 documentation 说:
Creates a directory by creating all nonexistent parent directories first.
(强调我的)
为了保持 JUnit 测试的可移植性和简单性,我建议完全删除外部文件依赖性。
您可以通过两种方式执行此操作:
从内部的东西创建一个 InputStream,比如字符串或字节数组。 Here is how with strings
使用模拟框架,例如 Mockito,创建一个虚拟 InputStream,其功能刚好足以确认该方法有效。这是我的首选策略,因为模拟会产生更清晰的测试。