Junit tests sharing same data object? Should I make a mock of it or what?
I have three classes I need to test, lets say Load, Transform, Perform and they all begin or work on the same data object, at least that's what is required, from one data object X the Load methods perform their thing on it, then it is given to Transform which also does its thing with its methods, and a Perform which changes the data object a bit and it is ready.
Now I want to write tests for Load, Transform and Perform.
The test-data object, should I jus开发者_运维知识库t make a static method in the Load class like
public static TestData makeTestData(...makeit...)
OR should I make a TestDataMock or TestDataTest class ? Which can return an example of it? And make a new TestDataTest class in each Load, Transform and Perform when they need to work on it?
You should always strive to make unit tests independent of each other. For that reason, you should always create any input test-data fresh for each test, whenever possible. What you want to test is "given input data X, verify that output is Y". JUnit has the @Before
annotation which you can use to annotate a method that is to be run before each test-case in that class. Typically, that is where you would put all your set-up code (creating and initilizing mock objects, creating or loading test-data, etc).
Alternativly, you could combine your Load, Transform and Perform actions into one test-case, but that would be more of an integration test than a unit test.
Sounds like a good example where dependencies would be useful, so you don't have to recreate the object every time (or worse, mock it). On top of that, you work with the real output produced by the previous phase, and you don't have to use statics (always a code smell).
JUnit doesn't support dependencies, but TestNG does:
@Test
public void load() { ... }
@Test(dependsOnMethods = "load")
public void transform() { ... }
@Test(dependsOnMethods = "transform")
public void perform() { ... }
If transform()
fails, the final report will say "1 Passed (load), 1 Failed (transform) and 1 Skipped (perform)"
, and you know exactly where to look.
Most test-case classes should be in the style of testcase class per class: if your have a class X it has one corresponding class XTest
. But that is not the only way of doing things; if you have a group of classes that cooperate you could use JUnit for some low-level integration testing of the cooperating classes. You need only think of a suitable name for this test-case class.
However, if you have a group of cooperating classes, consider hiding that fact behind a facade, or even just a single method call of some higher-level class. Then treat that facade or high-lelve method as something to unit-test.
Or, are you trying to say that you do not know how to test your three classes in isolation because they are very tightly coupled, and the behaviour of one can not be described without reference to the two others? That suggests you have a poor design: consider a redesign so you can describe the required behaviour of each class in isolation, and therefore test them (at least in part) in isolation.
精彩评论