java - 如何测试IO异常?

标签 java testing io

我的代码中有一个 WriterReader 对象,它使用 FileOutputStream 和 ObjectOutputStream。因此,将对象写入文件会引发 IO 异常。我正在尝试一种方法来处理 FileNotFound 异常并抛出其他 IO 异常。此外,在处理 FileNotFound 异常时,我想使用 JUnit 5 对其进行测试。

我尝试了以下测试,使用日期作为唯一文件名,断言该文件 DNE,然后将对象写入该 DNE 的文件,这应该触发 FileNotFound 异常。在处理该异常时,我基本上创建了一个同名的新文件,并在此之前创建了目录。

代码:

@Test
void testWriteReadObjectFileNotFound() {
    String timeStamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
    File file = new File("data\\test\\" + timeStamp );
    try {
        assertFalse(file.exists());
        System.out.println(file.exists());
        String s1 = "testObj";
        wr.writeObject(s1, file.getName());
        String s2 = (String) wr.readObject(file.getName());
        assertEquals("testObj", s2);
        assertTrue(file.exists());
    } catch (IOException e) {
        fail();
    } catch (ClassNotFoundException e) {
        fail();
    }
    file.delete();
}

//MODIFIES: file at filepath
//EFFECTS: Writes given object to file
public void writeObject(Object serObj, String fileName) throws IOException {
    FileOutputStream fileOut;
    ObjectOutputStream objectOut;
    try {
        new FileOutputStream(filepath + fileName);
    } catch (FileNotFoundException e) {
        File file = new File(filepath + fileName);
        file.getParentFile().mkdirs();
        file.createNewFile();
    } finally {
        fileOut = new FileOutputStream(filepath + fileName);
        objectOut = new ObjectOutputStream(fileOut);
        objectOut.writeObject(serObj);
        objectOut.close();
    }
}

但在我的代码覆盖范围内,它显示了以下行:

catch (FileNotFoundException e) {
        File file = new File(filepath + fileName);
        file.getParentFile().mkdirs();
        file.createNewFile();

不包括在内。有人能解释一下这种情况吗?

编辑:

在我用建议更新我的代码后,现在 intelliJ 显示我的测试涵盖了 write 方法,而在线 Jacoco Code Coverage 服务显示它根本没有涵盖。

session :

jdk.nashorn.api.scripting.NashornScriptEngineFactory    85de62d029761869
model.Coach 204e934c34a92289
model.CounterStrikePlayer   48cfc6cf38fe6003
model.Game  b60d406f9ed032d3
model.LeagueOfLegendsCoach  6a57ce5ef266c6fd
model.LeagueOfLegendsPlayer 9adbbaea6a1e6188
model.Player    6ce725a3657ac0c8
model.Team  13c05b5862e5b9a0
model.WriterReader  6a7b2968db1f8baa
modelTest.CoachTest 7271c28c53da6808
modelTest.CounterStrikePlayerTest   ee8e4647ff19f0c0
modelTest.GameTest  e5b8c02da0f18042
modelTest.LeagueOfLegendsCoachTest  9092faa361ca76c6
modelTest.LeagueOfLegendsPlayerTest f31d56fa7811133d
modelTest.PlayerTest    1dfe7a02c80688d8
modelTest.WriterReaderTest  a0c6c0b3c5015303
org.apiguardian.api.API.Status  0341e8d99fc36573
org.junit.jupiter.api.AssertEquals  ae120be259dc6039
org.junit.jupiter.api.AssertFalse   3ec30e2666af3771
org.junit.jupiter.api.AssertTrue    bf124afce44d2c84
org.junit.jupiter.api.AssertionUtils    4c69336af9422f48
org.junit.jupiter.api.Assertions    bef006507cf5ea35
org.junit.jupiter.api.DisplayNameGenerator  2fa57366e26f369e
org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores   a784705e370ef10a
org.junit.jupiter.api.DisplayNameGenerator.Standard 084b890848e1dd9c
org.junit.jupiter.api.TestInstance.Lifecycle    548dd47a98f9c8af
org.junit.jupiter.api.extension.ConditionEvaluationResult   2f9dc9ea54b57975
org.junit.jupiter.api.extension.ExtensionContext    1789eac1274261fc
org.junit.jupiter.api.extension.ExtensionContext.Namespace  cd5bcaed161aa28d
org.junit.jupiter.engine.JupiterTestEngine  86aefb99bb14b311
org.junit.jupiter.engine.config.CachingJupiterConfiguration bf4da7e3e8743286
org.junit.jupiter.engine.config.ClassNamePatternParameterConverter  db88e74320096433
org.junit.jupiter.engine.config.DefaultJupiterConfiguration 997c6d213eddc2c2
org.junit.jupiter.engine.config.EnumConfigurationParameterConverter 339f5752af685066
org.junit.jupiter.engine.descriptor.AbstractExtensionContext    9bf01323cf853683
org.junit.jupiter.engine.descriptor.ClassExtensionContext   41391528f2b447a4
org.junit.jupiter.engine.descriptor.ClassTestDescriptor 1c76f456279716b9
org.junit.jupiter.engine.descriptor.DisplayNameUtils    d2e15432c9a5ae11
org.junit.jupiter.engine.descriptor.ExtensionUtils  115ab989016caec3
org.junit.jupiter.engine.descriptor.ExtensionUtils.IsNonStaticExtensionField            1786ef465b5be8dc
org.junit.jupiter.engine.descriptor.ExtensionUtils.IsStaticExtensionField   31f9cde36a56bb92
org.junit.jupiter.engine.descriptor.JupiterEngineDescriptor 55f20ec61f78c1dc
org.junit.jupiter.engine.descriptor.JupiterEngineExtensionContext   37e3ac8bbe8deb47
org.junit.jupiter.engine.descriptor.JupiterTestDescriptor   4def5ef6cb345908
org.junit.jupiter.engine.descriptor.LifecycleMethodUtils    1162b59df6db6b33
org.junit.jupiter.engine.descriptor.MethodBasedTestDescriptor   c5a570f30b7fc2d2
org.junit.jupiter.engine.descriptor.MethodExtensionContext  afe114c2ffc920b7
org.junit.jupiter.engine.descriptor.TestInstanceLifecycleUtils  8d8758db35676c1c
org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor    8d3942c1a74c018c
org.junit.jupiter.engine.discovery.AbstractMethodResolver   2dfaf6ce646f2bdc
org.junit.jupiter.engine.discovery.DiscoveryFilterApplier   e52beeff7f999c17
org.junit.jupiter.engine.discovery.DiscoverySelectorResolver    ec3c5a90f0a97450
org.junit.jupiter.engine.discovery.JavaElementsResolver adc00610d0191f30
org.junit.jupiter.engine.discovery.MethodFinder 5ea468d2eb528361
org.junit.jupiter.engine.discovery.NestedTestsResolver  05fbe9d811da3eed
org.junit.jupiter.engine.discovery.TestContainerResolver    dfe41adaef62c3e4
org.junit.jupiter.engine.discovery.TestFactoryMethodResolver    0ad6df9dfc31ff24
org.junit.jupiter.engine.discovery.TestMethodResolver   c8d14bc2744286af
org.junit.jupiter.engine.discovery.TestTemplateMethodResolver   de3e832270e2401e
org.junit.jupiter.engine.discovery.predicates.IsInnerClass  f7d9846d00228720
org.junit.jupiter.engine.discovery.predicates.IsNestedTestClass e47ff7cd33073803
org.junit.jupiter.engine.discovery.predicates.IsPotentialTestContainer  fcb5565ad4483f6c
org.junit.jupiter.engine.discovery.predicates.IsTestClassWithTests  94179bc44f8c4ff7
org.junit.jupiter.engine.discovery.predicates.IsTestFactoryMethod   a2c68978bd6bfbc6
org.junit.jupiter.engine.discovery.predicates.IsTestMethod  8b244977e441886e
org.junit.jupiter.engine.discovery.predicates.IsTestTemplateMethod  0baf1066bf0cbad7
org.junit.jupiter.engine.discovery.predicates.IsTestableMethod  59a0b58a40803fe2
org.junit.jupiter.engine.execution.ConditionEvaluator   ed446ee9ecce3d2f
org.junit.jupiter.engine.execution.DefaultTestInstances 37fd85d961d60c98
org.junit.jupiter.engine.execution.ExecutableInvoker    cfec2160144fba71
org.junit.jupiter.engine.execution.ExtensionValuesStore b7ff2e73f692c652
org.junit.jupiter.engine.execution.JupiterEngineExecutionContext    d834be9bc6296452
org.junit.jupiter.engine.execution.JupiterEngineExecutionContext.Builder    2e7003b1ba1ccef9
org.junit.jupiter.engine.execution.JupiterEngineExecutionContext.State  d08acf502167b7f2
org.junit.jupiter.engine.extension.DisabledCondition    23223b45668b6ef2
org.junit.jupiter.engine.extension.ExtensionRegistry    3bd9c7c773d0274e
org.junit.jupiter.engine.extension.RepeatedTestExtension    1b7914cc8cf83732
org.junit.jupiter.engine.extension.ScriptExecutionCondition 72f1d00f1b0a51e3
org.junit.jupiter.engine.extension.ScriptExecutionCondition.Evaluator   36e29b1b3214594b
org.junit.jupiter.engine.extension.ScriptExecutionEvaluator c2e888183731e173
org.junit.jupiter.engine.extension.TempDirectory    34337e7d3f064058
org.junit.jupiter.engine.extension.TestInfoParameterResolver    1b5b370a56807cae
org.junit.jupiter.engine.extension.TestReporterParameterResolver    60beaf7c80fe99cc
org.junit.jupiter.engine.script.ScriptAccessor.EnvironmentVariableAccessor  c0c905d5fe8998ca
org.junit.jupiter.engine.script.ScriptAccessor.SystemPropertyAccessor   18fe4dab72ac1573
org.junit.jupiter.engine.script.ScriptExecutionManager  1f06dfe26cdafe2c
org.junit.jupiter.engine.support.JupiterThrowableCollectorFactory   be8bb2befc643502
org.junit.jupiter.engine.support.OpenTest4JAndJUnit4AwareThrowableCollector d5ffe1a3b602d0f0
org.junit.platform.commons.function.Try ed940444537e81c8
org.junit.platform.commons.function.Try.Failure 11c2a90efd237384
org.junit.platform.commons.function.Try.Success c4950437cb3f8d07
org.junit.platform.commons.logging.LoggerFactory    3ba683e3050bf0cd
org.junit.platform.commons.logging.LoggerFactory.DelegatingLogger   d773a9f74e627da2
org.junit.platform.commons.util.AnnotationUtils 2bc862bb4af7a8d1
org.junit.platform.commons.util.BlacklistedExceptions   bde618675b598c40
org.junit.platform.commons.util.ClassFileVisitor    fda6bee00014dc0f
org.junit.platform.commons.util.ClassFilter 093a789d01159576
org.junit.platform.commons.util.ClassLoaderUtils    c4b37ecc9a1c73f1
org.junit.platform.commons.util.ClassUtils  8883e6fc8a933271
org.junit.platform.commons.util.ClasspathScanner    e023789587082164
org.junit.platform.commons.util.CloseablePath   ece3194c27ee878f
org.junit.platform.commons.util.CollectionUtils 795bb2d3912e3e03
org.junit.platform.commons.util.ExceptionUtils  9cd3f0da74956a0f
org.junit.platform.commons.util.Preconditions   3a4283183815a888
org.junit.platform.commons.util.ReflectionUtils 230108a3d8877e27
org.junit.platform.commons.util.ReflectionUtils.HierarchyTraversalMode  e8178560b5d6126a
org.junit.platform.commons.util.StringUtils ae2f08e02cb55734
org.junit.platform.commons.util.ToStringBuilder 05623b120035b8d7
org.junit.platform.console.ConsoleLauncher  059adc8d410aa2fd
org.junit.platform.console.ConsoleLauncherExecutionResult   27f4bf4167ea4c68
org.junit.platform.console.options.AvailableOptions fdb77dc12d447dac
org.junit.platform.console.options.CommandLineOptions   7e55c6b93354950a
org.junit.platform.console.options.Details  94f00cde14a89870
org.junit.platform.console.options.DetailsConverter fcf24d774c4b2589
org.junit.platform.console.options.JOptSimpleCommandLineOptionsParser   dfe86502b5711f0b
org.junit.platform.console.options.KeyValuePairConverter    6479106b036169b8
org.junit.platform.console.options.Theme    efb1fee66cc0d8dc
org.junit.platform.console.options.ThemeConverter   84eb69368d7d50ef
org.junit.platform.console.options.UriConverter da7a6c694ecbadda
org.junit.platform.console.shadow.joptsimple.AbstractOptionSpec 332c05ea73b2a267
org.junit.platform.console.shadow.joptsimple.ArgumentAcceptingOptionSpec    e91fb45af3f25527
org.junit.platform.console.shadow.joptsimple.ArgumentList   20a1e6fa7ca1de2f
org.junit.platform.console.shadow.joptsimple.BuiltinHelpFormatter   1f4a9fd151488d57
org.junit.platform.console.shadow.joptsimple.NoArgumentOptionSpec   980fb4b32083f572
org.junit.platform.console.shadow.joptsimple.NonOptionArgumentSpec  a6617bf89ff60945
org.junit.platform.console.shadow.joptsimple.OptionParser   df3329f5c6910428
org.junit.platform.console.shadow.joptsimple.OptionParserState  46909cb366b4b20d
org.junit.platform.console.shadow.joptsimple.OptionParserState.2    21a8a5a1a79f3845
org.junit.platform.console.shadow.joptsimple.OptionSet  7775c7340e4c9c92
org.junit.platform.console.shadow.joptsimple.OptionSpecBuilder  2ee8eb9f9321ce9e
org.junit.platform.console.shadow.joptsimple.OptionalArgumentOptionSpec 99bf9f189db1b2cb
org.junit.platform.console.shadow.joptsimple.ParserRules    3ad47d297020a97d
org.junit.platform.console.shadow.joptsimple.RequiredArgumentOptionSpec ef502a894c5bf2f7
org.junit.platform.console.shadow.joptsimple.internal.AbbreviationMap   7d8bded7c479d774
org.junit.platform.console.shadow.joptsimple.internal.Classes   29161caedaa4619c
org.junit.platform.console.shadow.joptsimple.internal.MethodInvokingValueConverter  c8569bbc8a29f4d9
org.junit.platform.console.shadow.joptsimple.internal.Reflection    7b0a75eb5a86ebd8
org.junit.platform.console.shadow.joptsimple.internal.Rows  03ec8f4347813c4f
org.junit.platform.console.shadow.joptsimple.util.EnumConverter 0585b0c51b5b3266
org.junit.platform.console.shadow.joptsimple.util.KeyValuePair  a95c5f7d53974d82
org.junit.platform.console.shadow.joptsimple.util.PathConverter 7204d0c37dbcaa14
org.junit.platform.console.tasks.ConsoleTestExecutor    13bd936b734e2125
org.junit.platform.console.tasks.ConsoleTestExecutor.1  5210c580f0d62985
org.junit.platform.console.tasks.CustomContextClassLoaderExecutor   3f8d889927651162
org.junit.platform.console.tasks.DiscoveryRequestCreator    2406802947cbe928
org.junit.platform.console.tasks.XmlReportData  963ea32e5fdca9d4
org.junit.platform.console.tasks.XmlReportWriter    b2e8d74dcd772822
org.junit.platform.console.tasks.XmlReportWriter.TestCounts fb5108b5a5407430
org.junit.platform.console.tasks.XmlReportsWritingListener  fd7c2343d2db39e2
org.junit.platform.engine.CompositeFilter   ec8dc82249eeb7a9
org.junit.platform.engine.CompositeFilter.1 70825b5141694d2a
org.junit.platform.engine.ExecutionRequest  ed3835cc21e5a048
org.junit.platform.engine.Filter    f932423ccd3b54bf
org.junit.platform.engine.FilterResult  cdaa92f4f6f79059
org.junit.platform.engine.TestDescriptor    9fce516d5ec67d95
org.junit.platform.engine.TestDescriptor.Type   3d400391a113f4d2
org.junit.platform.engine.TestExecutionResult   fd67f84654a5aa1c
org.junit.platform.engine.TestExecutionResult.Status    26685ff07ec05579
org.junit.platform.engine.UniqueId  64973686b4e2c690
org.junit.platform.engine.UniqueId.Segment  1872a6198babd9f0
org.junit.platform.engine.UniqueIdFormat    7b04a7efceb2cec1
org.junit.platform.engine.discovery.AbstractClassNameFilter e8b93c76542ae539
org.junit.platform.engine.discovery.ClassNameFilter 61994645098fbceb
org.junit.platform.engine.discovery.ClasspathRootSelector   2e0a9607897269ad
org.junit.platform.engine.discovery.DiscoverySelectors  e41af1c3199080ae
org.junit.platform.engine.discovery.IncludeClassNameFilter  fb3d2855cc043d05
org.junit.platform.engine.support.descriptor.AbstractTestDescriptor 2bfbf25c43491443
org.junit.platform.engine.support.descriptor.ClassSource    309b80624638115b
org.junit.platform.engine.support.descriptor.EngineDescriptor   b7dbf6dfb794516c
org.junit.platform.engine.support.descriptor.MethodSource   e28a3ed844bb12d8
org.junit.platform.engine.support.filter.ClasspathScanningSupport   eecd7e41276fafb5
org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine   97ffbc145c7d4a83
org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor 68a36544a3925ed3
org.junit.platform.engine.support.hierarchical.LockManager  3b5f78863ff21738
org.junit.platform.engine.support.hierarchical.Node b49761977ceb7101
org.junit.platform.engine.support.hierarchical.Node.SkipResult  bd08edf24f1dd4d9
org.junit.platform.engine.support.hierarchical.NodeExecutionAdvisor e5cf54a3abfe8a32
org.junit.platform.engine.support.hierarchical.NodeTestTask 2d78f1925dd4882a
org.junit.platform.engine.support.hierarchical.NodeTestTask.DefaultDynamicTest    Executor  fdbc89e07549b13b
org.junit.platform.engine.support.hierarchical.NodeTestTaskContext  844fff78e0efe7ef
org.junit.platform.engine.support.hierarchical.NodeTreeWalker   b0b50dbbc8c467a5
org.junit.platform.engine.support.hierarchical.NodeUtils    d602362461bcf308
org.junit.platform.engine.support.hierarchical.NodeUtils.1  f707e15bc93748e1
org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService    054c281153908bb9
org.junit.platform.engine.support.hierarchical.ThrowableCollector   085e5d48a5acd8ee
org.junit.platform.launcher.TestIdentifier  225bb434f8f223e2
org.junit.platform.launcher.TestPlan    9a2b71b572924cbc
org.junit.platform.launcher.core.DefaultDiscoveryRequest    7dda3ad9a0e6a666
org.junit.platform.launcher.core.DefaultLauncher    1a1f88af87dc6ec1
org.junit.platform.launcher.core.ExecutionListenerAdapter   52cf3c3c69d4dfba
org.junit.platform.launcher.core.LauncherConfigurationParameters    ef55cacb5e47a902
org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder    e78a71b91c159e69
org.junit.platform.launcher.core.LauncherFactory    e2bd67b8a72737b5
org.junit.platform.launcher.core.Root   32394ca895f9fb9a
org.junit.platform.launcher.core.ServiceLoaderTestEngineRegistry    7c054c4cf76cb0f6
org.junit.platform.launcher.core.ServiceLoaderTestExecutionListenerRegistry 2299bac1075a6bf3
org.junit.platform.launcher.core.TestExecutionListenerRegistry  190f4fb2b0ab865d
org.junit.platform.launcher.core.TestExecutionListenerRegistry.CompositeTestExecutionListener   7538d2d860e1f9cb
org.junit.platform.launcher.listeners.LegacyReportingUtils  f3c021e100a54063
org.junit.platform.launcher.listeners.MutableTestExecutionSummary   01ebac90ede3a7fb
org.junit.platform.launcher.listeners.MutableTestExecutionSummary.DefaultFailure    e2d08dfc40cdf67e
org.junit.platform.launcher.listeners.SummaryGeneratingListener 2122f1c2f51ec894
org.junit.platform.launcher.listeners.SummaryGeneratingListener.1   e80fbdbe5858ce66
org.opentest4j.AssertionFailedError e810bc40602b9eed
org.opentest4j.ValueWrapper 68056fcd641fcfee

最佳答案

首先你错误地使用了try/catch结构。 您滥用异常工具作为控制结构。 应该是这样的:

public void writeObject(Object serObj, String fileName) throws 
    IOException {
        File theFile = new File(filepath + fileName);
        if(!theFile.exists()) {
            file.getParentFile().mkdirs();
            file.createNewFile();
        }

        try (FileOutputStream fileOut = new FileOutputStream(filepath + fileName);
             ObjectOutputStream objectOut = new ObjectOutputStream(fileOut)) {
             objectOut.writeObject(serObj);
        }
    }

有了这个,您的问题就变成了:我如何测试 if block ?

您可以通过将方法的第二个参数从 String 更改为 File 来实现:

public void writeObject(Object serObj, File theFile) throws IOException {
        if(!theFile.exists()) {
            file.getParentFile().mkdirs();
            file.createNewFile();
        }

        try (FileOutputStream fileOut = new FileOutputStream(filepath + fileName);
             ObjectOutputStream objectOut = new ObjectOutputStream(fileOut)) {
             objectOut.writeObject(serObj);
        }
    }

让此方法的调用者负责创建 File 对象。

然后在您的测试中,您可以传递一个mock 作为第二个参数。 使用 Mockito 作为模拟框架,测试将如下所示:

class Test { 
  private String timeStamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
  @Rule
  public final MethodRule mockito = MockitoJunit.rule(); 

  @Spy
  private File theFile = new File("data\\test\\" + timeStamp );

  @Mock
  private File theParent;

  @Before
  public void setup(){
     doReturn(theParent).when(theFile).getParentFile();
  }
  @Test
  void testWriteReadObjectFileNotFound() {
    // arrange
    doReturn(Boolean.FALSE).when(theFile).exists();
    String s1 = "testObj";
    // act
    wr.writeObject(s1, theFile);  
    // assert
    verify(theParent).mkdirs();
    verify.(theFile).createNewFile();
 }
}

关于java - 如何测试IO异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58401824/

相关文章:

如果我在 sql 中使用 'or' 而不是 'in',则 Java 堆空间不足错误

java - JSVC 和 Tomcat 7 的问题

sql - 基于ERD图的SQL的两道题。 (新手级别)

java - FilterInputStream 不执行

haskell - foldl 和 IO 值

linux - 2个并行连接中socket write()的公平性?

java - 在 JRE 1.7.4+ 中扩展 SocketChannel

java - PDFLib 意见/经验

testing - 如何为 Android Studio 创建小米模拟器?或任何其他方式来测试小米模拟器上的应用程序?

xcode - UI测试: completely skip app delegate