我有一个要测试的数据转换类。给出了接口ITransformer。该类如下所示:
public class MyDataTransformer implements ITranformer {
public MyDataTransformer() {}
@Override
public void init(String[] args) throws Exception {
if (args.length == 0)
throw (new Exception("bad input"));
// do initialization
}
@Override
public byte[] transform(byte[] input) {
try {
return transform_internal(input);
} catch (Exception e) {
return null;
}
}
private static byte[] transform_internal(byte[] input) throws Exception {
// do something
}
}
这是我目前拥有的测试班:
public class TransformerTest {
private MyDataTransformer transformer;
@BeforeClass
public void setUp() {
String[] args = new String[4];
// set args
try {
transformer = new MyDataTransformer();
transformer.init(args);
} catch (Exception e) {
fail(e.getMessage());
}
}
@Test
public void testTransform() {
byte[] input = read_input(); // omitted here for brevity
byte[] output = transformer.transform(input);
// this only tests if "valid" data was returned, but does not look into it
assertNotNull("Transformation failed", output);
// these 2 test some properties of the result data and should be separate tests
assertTrue("transformation step 1 failed", test_transformation_1(output);
assertTrue("transformation step 2 failed", test_transformation_2(output);
}
}
在测试方面,我遇到两件事。
首先,如何仅一次正确测试init
方法?从语义上讲,init属于@BeforeClass
块,但此块不是适当的测试。
第二,如何将test_transformation_1
分离到自己的测试中,但要确保仅在testTransform
成功完成后才能运行此测试(否则,对无效输入运行此测试是不明智的)。
在我看来,嵌套测试可以解决这两个问题,因此是问题的标题。但是,此示例可能会增加,我可能会添加不需要嵌套的独立测试,并且我想使其尽可能简单。
答案 0 :(得分:0)
是什么让您觉得它“明显地”属于BeforeClass?从语义上来说,测试属于您所测试类的任何方法的预期行为...属于 test 方法。不要进入准备休息的方法。
一个有意义的初始化方法将需要接收每个测试用例的设置数据。因此,如果有的话,您将有一个 MyDataTransformer underTest 字段,该字段将通过@Before方法初始化。使用以后可以进行正确测试的参数。
测试init方法的行为是否符合预期并抛出该异常属于一个独特的名为@Test的方法。
除此之外,您可以强制Junit以给定的顺序执行测试用例(例如按字典顺序排序)。那不是很好的做法,但是有时候可以解决此类订购问题。
答案 1 :(得分:0)
称为init的函数之间没有链接,并且在单元测试中应该只运行一次,也可以在每个函数之前运行。
使测试依赖另一个测试是一种不好的做法,您必须将其测试上下文分开,否则会导致噩梦,如果第二个测试依赖另一个测试,则可能会失败,因为第一个测试已更改了另一个测试。它们之间共享状态。因此,您正在缓慢寻找回归的根本原因,即使您决定按字母顺序排列测试,如果您在同一项目中工作的人很多,而又有人以不同的方式命名他的测试,您会发现...也很糟糕。
嵌套类的目的是按域对测试进行分组,从而提高测试的质量和可维护性。我在您的设计中看到的只是一个领域。
题外话: 出于可维护性的考虑,抛出通用的Exception类是一种专门的做法,这是不好的做法。 我也看到代码中有异味,为什么您为什么要在catch中返回,通常,您必须记录异常或将其抛出,并且返回必须在外部,另外,为了将来避免麻烦,请返回一个空数组为空。