Java 如果我想使用JUnit,是否禁止断言错误?

Java 如果我想使用JUnit,是否禁止断言错误?,java,unit-testing,junit,assert,Java,Unit Testing,Junit,Assert,我有一种方法,在特定的处理点期间,它希望保留某些不变量。 为了保持这一点,我们假设在代码处理过程中的X点处,变量high和变量low必须是可除的。 因此,在代码中,我会: if(high % low != 0){ throw new AssertionError("Invalid state of low and high [low = "+ low+ ", high=" + high+"]"); } 在使用JUnits进行单元测试期间,我有一个测试用例来测试这一点。 所以

我有一种方法,在特定的处理点期间,它希望保留某些不变量。
为了保持这一点,我们假设在代码处理过程中的X点处,变量
high
和变量
low
必须是可除的。
因此,在代码中,我会:

if(high % low != 0){  
  throw new AssertionError("Invalid state of low and high [low = "+ low+ ", high=" + high+"]");   
}   
在使用JUnits进行单元测试期间,我有一个测试用例来测试这一点。
所以我做了:

try {
//At this point I know for sure that the low and high are not divible so process() should throw an Assertion Error
   process();  
   fail();  
} 
catch(AssertionError e){        
}
但是测试用例是绿色的
但是我意识到junit由于
fail
而引发了一个断言错误,但我捕捉到了它,因此测试用例是通过的而不是失败的。
在我看来,在我的代码中提出的正确错误也是
AssertionError
,而不是一些通用的错误,例如
IllegalArgumentsException


那么,有没有一种方法可以解决这个问题,使测试用例能够工作,或者我应该首先在代码中不使用
AssertionError
?如果是这样,我应该提出什么例外

在单元测试中不应该有
try-catch
块。如果预期出现异常,请使用注释:

@Test(expected=Exception.class)
public void youTestMethod() {
   ...
}
您必须使用不同的异常,例如
IllegalArgumentsException
,因为JUnit在内部使用
AssertionError
。我发现,
IllegalArgumentsException
更能描述实际出了什么问题

boolean shouldFail = false;
try {
    callTheMethod();
    shouldFail = true;
}
catch (AssertionError e) {
    // expected
}
if (shouldFail) {
    fail();
}
但是如果条件是一个不变量,那么它应该始终为真,因此永远不会抛出AssertionError,因此您甚至不能对其进行单元测试。如果您能够测试它,这意味着不变量并不是一个真正的不变量,根据调用序列或提供的参数,条件可能是真的。因此,您应该更喜欢非法声明,而不是断言错误

 > should I not be using the AssertionError in my code in the first place? 
//test case setup
yourClass.callYourMethod(4,2);
//verification
JUnit正在使用AssertionError及其Decentant告诉JUnit运行程序测试失败。(Simmilar适用于.net NUnit runner)


我会使用一个通用的异常,比如
IllegalArgumentsException
,或者创建我自己的异常

是的,您的代码和JUnit之间存在冲突,但很容易解决

当您编写JUnit测试用例时,正如您已经推断的那样,当测试用例失败时会抛出AssertionError

为了让JUnit知道您的测试用例已经通过,测试代码不应该在任何其他异常/错误上抛出AssertionError

将有两个测试用例(至少)-

高和低是完全可分的——测试用例代码不会抛出断言错误

 > should I not be using the AssertionError in my code in the first place? 
//test case setup
yourClass.callYourMethod(4,2);
//verification
在这里,如果测试用例的行为正确,那么就没有AssertionError,JUnit知道它已经通过了

高和低不是完全可分的-代码应该抛出AssertionError,但测试用例不应该

boolean failed;
try {
    //test case setup
    yourClass.callYourMethod(4,2);
    failed = true;
} catch (AssertionError e) {
    failed = false;
}
if (failed) {
    fail();
}

在我的JUnit(4.10)版本中,它抛出java.lang.AssertionError.Hmmm。你是对的,我想知道他们为什么这么做。你不同意在这里使用注释吗?不。但我不同意使用AssertionError。见我的答案和评论。我不同意关于不变量的论点。你是对的,这确实取决于所提供的参数(但间接地说,
high
low
是从传递的参数派生出来的),而且
high
low
应该总是可除的事实必须始终成立。这难道不构成不变量吗?不变量是某种布尔条件,由类本身保证始终为真。如果这个条件只有在提供的参数正确时才成立,那么它就不再是一个不变量了。使其成为不变量的方法是,如果参数使不变量为false,则拒绝这些参数。为了拒绝非法参数,您抛出一个IllegalArgumentException。例如,Person类可以具有变量:
age>0
。方法setAge(int age)应该通过抛出一个IllegalArgumentException来保证这个不变量,如果age是,这是一个好的解决方案。这里有两种选择:(#1)抛出不同的异常,而不是AssertionError。如果需要,创建自己的异常类。(#2)我最常检查catch块中的异常消息:assertEquals(“低和高的无效状态[low=2,high=11]”,e.getMessage())我最好将其重写为
try{callTheMethod();fail(“应该永远不要到这里”)}catch(断言者e){//expected}
@DmitryZvorygin这就是OP的功能。把问题再读一遍。