JUnit Best Practice: Different Fixtures for each @Test
I understand that there are @Before
and @BeforeClass
, which are used to define fixtures for the @Test
's. But what should I use if I need different fixtures for each @Test
?
- Should I define the fixture in the
@Test
? - Should I create a test class
for each
@Test
?
I am asking for the best practices here, since both solutions aren't clean in my opinion. With the first solution, I would test the initialization code. And 开发者_JAVA百科with the second solution I would break the "one test class for each class" pattern.
Tips:
- Forget the one test class per class pattern, it has little merit. Switch to one test class per usage perspective. In one perspective you might have multiple cases: upper boundary, lower boundary, etc. Create different @Tests for those in the same class.
- Remember that JUnit will create an instance of the test class for each @Test, so each test will get a distinct fixture (set up by the same @Before methods). If you need a dissimilar fixture you need a different test class, because you are in a different perspective (see 1.)
- There is nothing wrong with tweaking the fixture for a particular test, but you should try to keep the test clean so it tells a story. This story should be particularly clear when the test fails, hence the different, well named @Test for each case (see 1.)
I would suggest to create a separate Class based on the different fixtures you need. If you have two different fixtures you need just create two different classes (give them a convenient name). But i would think a second time about that, in particular about the difference in the fixtures and why are the different. May be you are on the way to a kind of integration test instead of unit test?
If you are positive that your fixture is unique to single test then it belongs to @Test
method. This is not typical though. It could be that some part of it is unique or you didn't parametrize/extracted it right, but typically you will share a lot of the same data between tests.
Ultimately fixture is part of the test. Placing fixture in @Before
was adopted as xUnit pattern because tests always:
- prepare test data/mocks
- perform operations with SUT
- validate/assert state/behavior
- destroy test data/mocks
and steps 1 (@Before
) and 4 (@After
) are reused a lot (at least partially) in related tests. Since xUnit is very serious about test independence it offers fixture methods to guarantee that they always run and test data created/destroyed properly.
精彩评论