- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我最近发现 JUnit > 4.10 允许使用 @Rule
和 ExpectedException
。由于我不太喜欢复制代码,所以我尝试了以下方法。为了更好地理解,我将它从几个测试缩减为这两个。 MockitoJUnitRunner
是有意为之的,尽管它没有在小规模示例中使用。
pom.xml
<dependencies>
<!-- Test dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
</dependencies>
测试库
@RunWith(MockitoJUnitRunner.class)
public class TestBase {
/** JUnit > 4.10 allows expected exception handling like this */
@Rule
public ExpectedException exception = ExpectedException.none();
@Before
public void setup() {
this.expectBadParam();
}
protected void expectBadParam() {
this.exception.expect(NullPointerException.class);
}
}
问题是下面的测试没有像我预期的那样工作。我正在尝试的是默认情况下期望异常类型,并且在某些情况下运行正常的 JUnit 测试。设置后我无法重置预期的异常。
public class ExpectedExceptionTest extends TestBase {
@Test
public void error() {
throw new NullPointerException();
}
@Test
public void success() {
this.exception = ExpectedException.none();
// this should be a success
}
}
我已经找到了不同的解决方案,方法是在每个方法中复制 expectBadParam 方法,我希望出现异常,并覆盖测试类中的 @Before
注释。但是我希望有人能帮助我理解为什么这不起作用?
最佳答案
它没有像您预期的那样工作(没有双关语意)的原因与 TestRule
如何与 JUnit 一起工作有关。
实际上,测试框架会检查测试用例中的 TestRule
实例,然后依次调用每个实例的 TestRule.apply()
方法。此方法接受一个 Statement
对象并返回一个 Statement()
。您的测试用例对象最初包装在一个声明中,提供给第一个 TestRule,它返回一个全新 Statement
包装原始 Statement
。因此,基本上,TestRule 有机会适应 原始的 TestCase,通常会添加新功能。一旦框架遍历了所有 TestRule 实例,它就会调用 Statement.evaluate()
方法,就像它对它构建的任何“标准”测试用例所做的那样,它没有附加任何 TestRules
这里的关键是框架和 TestRule
实例之间的所有交互都发生在测试用例构建时。一旦建立了测试用例,包含规则的字段就不再被测试框架查询或直接与之交互。他们之后的主要目的是让测试与规则中包含的可变状态进行交互。因此,如果您像在测试用例 success()
中那样更改实例字段,您将对规则的结果完全没有影响,因为该规则需要一个 IllegalArgumentException
已经应用于测试用例。
TestRule
实现有一个“典型”的形状。他们看起来像这样......
public void apply(Statement base, Description description) {
return new Statement() {
public void evaluate( ) {
// some initialisation
try {
base.evaluate();
} finally {
// some tidy up here
}
}
}
}
这里,TestRule 有机会在测试用例完成后运行一些代码。这就是 ExpectedException 的工作原理(尽管它也有一个“catch Exception(e)” block )。在测试过程中,您可以调用规则实例上的方法,该实例在 TestRule 对象中建立状态,然后在调用 finally block 时使用该对象。因此,当您调用“exception.expect(IllegalArgumentException.class)”时,测试规则将一个匹配器存储在列表中,并使用该匹配器和您可能已设置的任何其他匹配器基本上匹配捕获的异常。当您重置测试用例中的实例字段时,原始实例中的所有状态仍然存在,因此测试仍然失败。
要执行您想执行的操作,您需要一种重置 ExpectedException
实例的内部状态的方法。遗憾的是,ExpectedException
类中没有任何方法可让您删除已添加的期望值。只有真正有可能增加期望。而且,老实说,这是有充分理由的——您的测试应该按逻辑分组,在您越接近测试用例时添加更细粒度的细节。 “重置”期望的行为是删除而不是添加细节的行为,因此表明您的测试在逻辑上分组得不够好。如果测试套件的某些部分增加了一些期望,而另一部分删除了部分/全部期望,则会造成可维护性困难。
如果您想在这里使用 ExpectedException,您有 2 个选择。第一个是将您的测试类或测试基类一分为二。一个套件应该用于期望 IllegalArgumentException 的测试,另一个套件用于那些不期望或具有他们期望的某种替代异常的测试。第二个是接受固有的重复,因为有 44 个测试必须明确声明它们期望异常,而只有 4 个测试没有。
您可能能够以某种方式使用 JUnit Theories
实现您想要的,尽管这在很大程度上取决于您的测试用例的工作方式。
关于java - 是否可以覆盖 JUnit 中的预期异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41364173/
我对java有点陌生,所以如果我犯了一个简单的错误,请原谅我,但我不确定我哪里出错了,我收到的错误是“预期的.class,预期的标识符,而不是声明, ';'预期的。”我尝试了不同的方法,并从这些方法中
This question already has answers here: chai test array equality doesn't work as expected (3个答案) 3年前
我正在学习 Java(对不起,我的英语很差,这不是我的母语),当我在 Eclipse (JavaSE-1.7) 中在我输入的每个“try”中执行“try-finally” block 时,会出现以下消
我收到两个错误,指出 token 上的语法错误,ConstructorHeaderName expected instead & token “(”上的语法错误,< expected 在线: mTM.
我找不到错误。 Eclipse 给我这个错误。每个 { } 都是匹配的。请帮忙。 Multiple markers at this line - Syntax error on token “)”,
代码: import java.awt.*; import javax.swing.*; import java.awt.event.*; public class DoubleIt extends
我正在用 python(Vs 代码)编写代码,但出现此错误: Expected ")" Pylance 错误发生在:def main() 我试着运行我的 main 并将它打印到我的屏幕上。我用谷歌搜
我正在尝试按照 documentation 中的建议使用异步函数。但我收到此错误 意外的 token ,预期 ( async function getMoviesFromApi() { try
Closed. This question does not meet Stack Overflow guidelines。它当前不接受答案。 想改善这个问题吗?更新问题,以便将其作为on-topic
Closed. This question does not meet Stack Overflow guidelines。它当前不接受答案。 想改善这个问题吗?更新问题,以便将其作为on-topic
第一行包含一个表示数组长度的整数p。第二行包含用空格分隔的整数,这些整数描述数组中的每个元素。第三行打印一个整数,指示负数组的数量。 package asgn3; import java.util.*
好的,我是初学者,我必须修复此 java 表达式语言代码才能在我的系统 (Windchill) 中工作,但看起来我在语法中遗漏了一些内容: LWCNormalizedObject lwc =
我无法编译我的程序! 我想我缺少一个花括号,但我怎么也看不出在哪里! import javax.swing.*; import java.awt.*;
我的 jQuery 代码有问题,我的 Firebug 向我发出警告:需要选择器。 这是代码: $("img[id$='_tick']").each(function() { $(this).c
我的新类(class) Fountainofyouth 遇到了问题。尝试构建整个项目后,调试器显示 warning: extended initializer lists only available
我已经从 Java 转向 CPP,并且正在努力围绕构造构造函数链进行思考,我认为这是我的问题的根源。 我的头文件如下: public: GuidedTour(); GuidedTour(string
鉴于以下 for(var i=0; i< data.cats.length; i++) list += buildCategories(data.cats[i]); jsLint 告诉我 Expect
我有这个 json,但 Visual Studio Code 在标题中给了我警告。 [ { "title": "Book A", "imageUrl": "https:
我正在尝试编写一个有条件地禁用四个特殊成员函数(复制构造、移动构造、复制赋值和移动赋值)的包装类,下面是我用于测试目的的快速草稿: enum class special_member : uint8_
所以我用 F# 编写了一个非常简单的程序,它应该对 1000 以下的所有 3 和 5 的倍数求和: [1..999] |> List.filter (fun x -> x % 3 = 0 || x %
我是一名优秀的程序员,十分优秀!