JavaSE7:测试用TryCatch的替代方案

JavaSE7:测试用TryCatch的替代方案,java,junit,try-catch,Java,Junit,Try Catch,在一个测试类中,我从beforeTest()之前的@调用了一系列类似的方法: //... private void addClientDetails() { try { clientDetailsService.addClientDetails(testClient); } catch (Exception e) { } } private void addUserRoles() { try { adminController.

在一个测试类中,我从beforeTest()之前的
@调用了一系列类似的方法:

//...

private void addClientDetails() {
    try {
        clientDetailsService.addClientDetails(testClient);
    } catch (Exception e) {
    }
}

private void addUserRoles() {
    try {
        adminController.addUserRoles(addedRoles);
    } catch (Exception e) {
    }
}

private void deleteAddedRoles() {
    for (String role : addedRoles) {
        try {
            adminController.deleteUserRole(role);
        } catch (Exception e) {
        }
    }
}

private void deleteClients() {
    try {
        clientsController.deleteClient(testClient.getClientId());
    } catch (Exception e) {
    }
}

//...
没有必要捕捉可能的异常,在这里添加一些ifs也很不方便。这些是准备试验或试验后清理的辅助方法

如何摆脱那些荒谬的
尝试{…}catch(…){}
构造?

其想法是创建一个带有
Runnable
参数的新方法,但这会导致更麻烦的语法:

private void deleteClients() {
    trySilently(new Runnable() {
        @Override
        public void run() {

        }
    });
}

private void trySilently(Runnable task) {
    try {
        task.run();
    } catch (Exception e) {
        //do nothing
    }
}
在JDK1.8方法参考中可以有所帮助。但是JDK1.7有什么好的解决方案吗


可以理解,忽略异常是一种糟糕的做法。尽管如此,问题还是在于如何以优雅的方式执行此操作。

您可以声明这些方法会引发异常,例如:

private void addClientDetails() throws Exception {
    clientDetailsService.addClientDetails(testClient);
}
…然后使用反射调用它们:

String[] methods = {"addClientDetails", "addUserDetails" /*, ...*/};
for (String method : methods) {
    try {
        TestClass.class.getMethod(method).invoke(testObject);
    }
    catch (Exception e) {
        // STRONGLY RECOMMEND DOING SOMETHING HERE SO YOU'RE NOT SILENTLY
        // IGNORING EXCEPTIONS
    }
}
(不过,如果确实要忽略来自
admincontroler.deleteUserRole
的异常,则需要将处理程序保留在
deleteAddedRoles
中,因为它会循环)



注意:完全忽略这些例外情况似乎很奇怪。如果默默地忽略测试代码中的异常,很难想象您如何信任您的测试结果。但我假设你知道你在做什么…:-)

在TestNG中,用@BeforeClass/@beforethod注释的方法抛出异常是没有问题的

你为什么不干脆

@BeforeClass
private void addClientDetails() throws Exception{
     clientDetailsService.addClientDetails(testClient);
}
这也适用于@Test方法

愚蠢地捕捉异常是非常糟糕的主意。那你怎么能相信你的测试呢?您确定发生的异常确实没有问题吗?如果是,则不应首先抛出异常


此外,还可以重新设计API以使用未检查的异常。只需将所有选中的异常包装到RuntimeException中,然后抛出RuntimeException

为什么要忽略这些异常?当然这就是你测试的目的。如果您想知道异常何时发生,只需将
抛出异常
添加到测试方法的签名中。让您的方法抛出异常,忽略异常是一种可怕的做法,永远不应该这样做。可能你最好使用许多模拟框架中的一个,而不是像那样编写存根。我无法想象如果你默默地忽略测试方法引发的异常,你怎么能相信你的测试结果。正如我在问题中指出的,这些不是测试用例,我总是确保测试结果是可信的,因为如果其中一个方法中发生了一些非常糟糕的事情,并且将被忽略,那么我将在后续调用中得到断言错误。但通常我会犯一些错误,比如“某些东西已经存在”或“不存在”。这我不在乎,因为我只需要确保我尝试添加/删除了一些东西。”然后使用反射来称呼他们:“yuk-yuk-yuk-yuk-yuk-yuk-yuk-yuk。这似乎是一个错误的建议——OP应该理解抛出这些异常的原因,从而正确地处理它们。@AndyTurner:正如我上面所说的,忽略这些异常似乎是一个错误的想法。但是OP没有征求异常处理方面的建议,只是询问如何避免所有这些尝试忽略(我喜欢称之为尝试忽略)。:-)我相信反射就是在Java 7中循环一系列方法的方式,所以……如果这些方法是测试用例,那么最好将OP指向JUnit或其他标准测试框架,而不是像这样滚动自己的测试框架。如果它们不是测试用例,则不需要在循环中调用它们。(是的,JUnit在封面下使用了反射;但它做的是合理的默认操作,不需要重新设计)@AndyTurner:我只是回答OP实际提出的问题。已经有很多评论指出他被要求做的是一个坏主意,包括至少一个指向测试框架的评论。你是第一位,但是所有关于反射的东西都是关于OP如何调用这些私有方法的假设。想必它们已经被调用了,不知何故;没有理由改变这一点(除了可能传播这些方法中的
抛出的
)。