Unit Tests for JPA/Persistence in General
How/would you test super-simple methods that are built on a persistence engine. I'm going to use JPA but any persistence mechanism I'm sure has its equivelents.
For example...
@Entity
public class Category {
@Id @GeneratedValue
private long id;
@NotNull @NotEmpty
private String name;
@NotNull
@ManyToOne
private User user;
//...Getters/Setters...
}
@Stateless
public void CategoryServiceImpl implements CategoryService {
@PersistenceContext EntityManager entityManager;
public void addCategory(Category input) {
entityManager.persist(inpu开发者_运维问答t);
}
}
What kind of tests would be useful for addCategory. I can see the usefulness of TDD and unit testing but I'm just not sure what kinds of tests to do for simple methods like that. Not really looking for "how" to create the tests but "what" to test.
One philosophy is to be very hard-nosed about unit testing (before I explain what I mean, let me say that I rarely follow this philosophy myself). You are testing that this unit does what it is supposed to do, not that any depedent software (such the the persistence mechanism) works.
So this method of your receives a parameter "input" and passes it to entityManager.persist. That's it's job. So we use a mocking framework of some sort to get a mock entityManager, and we verify that indeed the parameter passed to the call of addCategory is received my the entityManager. That's it. We've tested all the responsibilities of the method.
In more complex scenarios this appraoch is pretty useful, you test all the conditionals in the method and pick up all sorts of "off-by-one" and misuse of null reference errors etc.
For something like this example I'm not convinced that we are going to find the interesting bugs. So I'd be setting up little suites of tests using a real EntityManager, which push the boundaries of the data. And yes, this isn't truly "Unit" testing, but I don't care - I want to find defects!
For example:
Create a category object with an empty name
Call Add Category
What should happen? I assume that we intend that an exception be thrown? So we test that indeed that's what happens.
Some more tests:
- Insert, then retrieve - verify all fields
- Insert, then insert a duplicate, what error do we expect
and so on.
Instead of integration testing against an existing database you can perform decent unit tests by running your tests against an embedded in memory database like h2 which has been configured to create all its tables based on the annotations on connection. This works well for us for a database of about two hundred tables.
精彩评论