JUnit:使用构造函数而不是@Before

vbe*_*nce 66 junit constructor initialization

我正在使用JUnit 4.我看不出构造函数初始化或使用注释的专用init函数之间的区别@Before.这是否意味着我不必担心它?

有没有什么@Before比在构造函数中进行初始化更多的情况?

Pét*_*rök 80

不,使用构造函数初始化JUnit测试夹具在技术上等于使用该@Before方法(由于JUnit为每个测试类创建了一个新的测试类实例@Test).唯一(内涵)的区别在于它打破了@Before和之间的对称性@After,这可能会让一些人感到困惑.恕我直言,最好遵守惯例(正在使用@Before).

还要注意,在JUnit 4和注释之前,有专用setUp()tearDown()方法 - @Before@After注释取代了这些,但保留了底层逻辑.因此,使用注释还可以使从JUnit 3或更早版本迁移的人员的生活更轻松.

显着的差异

评论的更多细节:

  • @Before 允许重写父类行为,构造函数强制您调用父类构造函数
  • 构造函数子类构造函数和@Rule方法之前@Before运行,所有这些之后运行
  • 在调用@Before原因@After方法期间的异常,构造函数中的异常不会

  • 与此同时,我读到了一个重要的区别:如果在构造函数*中抛出*异常,那么将没有对象运行`@ After` on.所以我一直使用注释,只保留最小的构造函数. (8认同)
  • @Sylvain,因为JUnit为每个测试方法创建一个新的测试类实例,构造函数和`@ Before`被称为完全相同的次数. (3认同)
  • @Before多次被调用?(在每种测试方法之前?) (2认同)
  • @DerekMahar,更不用说并非所有xUnit克隆在这方面都表现相同.例如,NUnit不为每个测试方法执行创建测试类的新实例,因此使用构造函数而不是`[SetUp]`方法(NUnit相当于`@ Before`)实际上是一个错误.对我来说,这类似于"依赖接口,而不是实现"maxime,使得一个代码更容易携带,并且从长远来看更容易维护. (2认同)
  • @PéterTörök,我不知道NUnit没有遵循这个惯例.我想你已经说服我使用`@ Before`是一个好主意,虽然让我感到困扰的是当使用`@ Before`时,我不能让我的数据成员引用最终. (2认同)

小智 26

@Before在某些情况下使用更有意义,因为它在类的构造函数之后被调用.当您使用像Mockito这样的模拟框架和@Mock注释时,这种差异非常重要,因为在模拟初始化之后将调用@Before方法.然后,您可以使用模拟为被测试的类提供构造函数参数.

在使用协作bean时,我发现这是我单元测试中非常常见的模式.

这是一个(公认的人为)例子:

@RunWith(MockitoJUnitRunner.class)
public class CalculatorTest {
    @Mock Adder adder;
    @Mock Subtractor subtractor;
    @Mock Divider divider;
    @Mock Multiplier multiplier;

    Calculator calculator;

    @Before
    public void setUp() {
        calculator = new Calculator(adder,subtractor,divider,multiplier);
    }

    @Test
    public void testAdd() {
        BigDecimal value = calculator.add(2,2);
        verify(adder).add(eq(2),eq(2));
    }
}
Run Code Online (Sandbox Code Playgroud)


Der*_*har 9

我更喜欢使用构造函数初始化我的测试对象,因为它允许我创建所有成员,final以便IDE或编译器告诉我何时构造函数忘记初始化成员并阻止其他方法设置它们.

恕我直言,@Before违反了最重要的Java约定之一,依赖于构造函数来完全初始化对象!


thS*_*oft 5

我更喜欢将我的fixtures声明为final并在内联或构造函数中初始化它们,所以我不会忘记初始化它们!但是,由于@Before中抛出的异常以更加用户友好的方式处理,我通常会在@Before中初始化测试中的对象.


归档时间:

查看次数:

39144 次

最近记录:

6 年,7 月 前