Java 将两个jUnit测试用例合并为一个

Java 将两个jUnit测试用例合并为一个,java,eclipse,junit,junit4,testcase,Java,Eclipse,Junit,Junit4,Testcase,我有以下两个junit测试用例: @Test(expected=NullPointerException.class,timeout=2000) public void X1() { abc.xyz(null); fail("Car xyz() should throw NullPointerException when adding null items"); } @Test(expected=NullPointerException.class,timeout=2000)

我有以下两个junit测试用例:

@Test(expected=NullPointerException.class,timeout=2000)
public void X1()
{
    abc.xyz(null);
    fail("Car xyz() should throw NullPointerException when adding null items");
}

@Test(expected=NullPointerException.class,timeout=2000)
public void Y1()
{
    abc.pqr(null);
    fail("Car pqr() should throw NullPointerException when adding null items");
}
我想把上面两个测试用例合并成一个。我该怎么办呢?

你真的不想把这些案例合并在一起。他们在测试完全不同的东西

在第一次测试中,您使用
null
测试
xyz
的结果。在第二个测试中,您正在使用
null
测试
pqr
。如果您想检查这些测试的边界条件,那么这两个测试都可以编写和使用

如果任一方法的行为发生变化,在此方案中,您只需重写一个测试。也就是说,如果
pqr
突然变得允许空值,并且您在一次测试中将它们混合在一起,您仍然会得到测试失败,因为
xyz
不允许空值


把这些分开。您既不希望也不需要将这些测试用例组合在一起。

同意Makoto的观点,即这样做是非常糟糕的,并且违背了任何类型的最佳实践。同样值得怀疑的是,为什么您的组织会关心这种低级别的单元测试实现。。。无论如何

@Test
public void xyzAndPqr(){

Throwable thrown;
try{
   abc.pqr(null);
catch(Throwable e){
   thrown = e;
}

  //assert thrown
assertThat(thrown,instanceOf(NullPointerException.class));
//assert anything else, null var or create another...
thrown = null;

try{
    abc.xyz(null);
catch(Throwable e){
   thrown = e;
}

assertThat(thrown,instanceOf(NullPointerException.class));
//assert anything else
如果需要,在它们的公共库中还有一些Apache ExceptionUtil来获取消息等

如果您使用的是Java8,那么AssertJ库可以处理这个比较干净的问题


使用attribute
expected
是一个非常弱的解决方案,因为您无法控制该方法的哪个指令将引发异常

即使我不明白加入他们的原因。。。这里有一些解决方案:

JUNIT4

@Test
public void xyzAndPqr(){

  try {
    abc.pqr(null);
    fail("pqr does not throw NullPointerException");
  } catch(NullPointerException npe) {};

  try {
    abc.xyz(null);
    fail("xyz does not throw NullPointerException");
  } catch(NullPointerException npe) {};

}
注意:捕获只接受NullPointerException,因此如果方法引发其他类型的异常,测试将正确失败

注1:在catch子句中,您可以检查附加条件(消息、原因等)

注2:第一种不正确的方法测试失败,未检查其余方法。要始终检查所有方法,可以使用收集器规则

JUNIT5

import static org.junit.jupiter.api.Assertions.*;
@Test
public void xyzAndPqr(){
   assertThrows(NullPointerException.class, () -> abc.pqr(null));
   assertThrows(NullPointerException.class, () -> abc.xyz(null));
}
注意:如果需要检查其他条件(消息、原因等),assertThrows将返回有效的提升可丢弃项

注1:第一种不正确的方法测试失败,未检查其余方法。要始终检查所有方法,可以使用AssertAll

import static org.junit.jupiter.api.Assertions.*;
@Test
public void xyzAndPqr(){
  AssertAll(
   () -> assertThrows(NullPointerException.class, () -> abc.pqr(null)),
   () -> assertThrows(NullPointerException.class, () -> abc.xyz(null))
  );
}   
JUNIT(4和5)和AssertJ (见附件)

注意:您可以在assertJ中使用流畅的语法:例如添加.withMessage(“…”)


注1:第一种不正确的方法测试失败,未检查其余方法。要始终检查所有方法,您可以使用AssertAll(如果在JUnit5中)或assertJ软断言(在这两种情况下)

我知道,我已经考虑过您提到的内容,但我所在的组织希望我将测试用例合并为一个。我似乎没有选择的余地:测试这些东西的目的是孤立地测试它们。通过将这两种方法结合起来,您可能会面临测试不可靠和重构时信心不足的风险。把这些结合起来是一个错误,我不能说得足够强烈。虽然合并它们很容易,但您不想这样做。为什么组织要合并它们?与@Makato的答案相比,有什么好处/理由?我知道将它们结合起来没有任何用处,只是这是我的一个要求。你能帮我把它们合起来吗?
import static org.junit.jupiter.api.Assertions.*;
@Test
public void xyzAndPqr(){
  AssertAll(
   () -> assertThrows(NullPointerException.class, () -> abc.pqr(null)),
   () -> assertThrows(NullPointerException.class, () -> abc.xyz(null))
  );
}   
import static org.assertj.core.api.Assertions.*;
@Test
public void xyzAndPqr(){
   assertThatNullPointerException().isThrownBy( () -> abc.pqr(null) );
   assertThatNullPointerException().isThrownBy( () -> abc.xyz(null) );
}