Unit Tests for JPA/Persistence in General - unit-testing

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(input);
}
}
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.

Related

What is the controller allowed to assume about what it recieves from a service?

Quick terminology question that's somewhat related to my main question: What is the correct term for a model class and the term for a instance of that class?
I am learning Test Driven Development, and want to make sure I am learning it the right so I can form good habits.
My current project has a SalesmanController, which is pretty much a basic resource controller. Here's my current issue (I can get it working, but I want to make sure its done as "right" as possible)
I have a 'Salesman' model.
The 'Salesman' is mapped as having many 'Sales' using my ORM.
The 'Sales' model is mapped as belongsTo 'Salesman' using my ORM.
I have created a ORMSalesmanRepository which implements the SalesmanRepositoryInterface.
My controller has SalesmanRepositoryInterface passed to it upon construction(constructor dependency injection).
My controller calls the find method on the SalesmanRepositoryInterface implementation it has been given to find the correct salesman.
My view needs information on the salesman and information on all 'Sales' records that belong to him.
The current implementation of SalesmanRepositoryInterface returns an instance of a ORMRecord, and then passes that to the view, which retrieves the sales from the ORMRecord.
My gut tells me this implementation is wrong. The orm record implements Array Access, so it still behaves like an array as far as the view knows.
However, when trying to go back and implement my unit tests I am running into issues mocking my dependencies. (I now know with TDD I'm supposed to make my unit tests and then develop the actual implementation, didn't figure this out till recently).
Salesman = MockedSalesman;
SalesRecords = MockedSalesman->Sales;
Is it poor programming to expect my Salesman to return a ORMObject for the controller to use (for chaining relationships maybe?) or is a controller becoming to 'fat' if I'm allowing it to call more than just basic get methods (using arrayaccess []) on the ORMObject? Should the controller just assume that whatever it gets back is an array (or at least acts like one?)
Also, should it ever come up where something one of my mocked classes returns needs to be mocked again?
Thanks in advance everybody.
What is the correct term for a model class and the term for a instance of that class?
Depends on what you mean with "model classes"? Technically model is a layer, that contains several groups of classes. Most notable ones would be: mappers, services an domain objects. Domain objects as whole are implementation of accumulated knowledge about business requirements, insight from specialists and project goals. This knowledge is referred to as "domain model".
Basically, there is no such thing as "model class". There are classes that are part of model.
What is the controller allowed to assume about what it recieves from a service?
Nothing, because controller should not receive anything from model layer. The responsibility of controller is to alter the state of model layer (and in rare cases - state of current view).
Controller is NOT RESPONSIBLE for:
gather data from model layer,
initializing views
passing data from model layer to views
dealing with authorization checks
The current implementation of SalesmanRepositoryInterface returns an instance of a ORMRecord, and then passes that to the view, which retrieves the sales from the ORMRecord.
It sounds like you are implementing active record pattern. It has very limited use-case, where is is appropriate to use AR - when object mostly consists of getters and setters tht are directly stored in a single table. For anything beyond that active record becomes an anti-pattern because it violates SRP and you loose the ability to test your domain logic without database.
Also, are repository should be returning an instance of domain object and makes sure that you are not retrieving data repeatedly. Repositories are not factories for active record instances.
Is it poor programming to expect my Salesman to return a ORMObject for the controller to use (for chaining relationships maybe?) or is a controller becoming to 'fat' if I'm allowing it to call more than just basic get methods (using arrayaccess []) on the ORMObject?
Yes, it's bad code. Your application logic (one that would usually be contained in services) is leaking in the presentation layer.
At this stage I wouldn't stress too much about your implementation - if you try and write proper tests, you'll quickly find out what works and what doesn't.
The trick is to think hard about what each component is trying to achieve. What is your controller method supposed to do? Most likely it is intended to create a ViewModel of some kind, and then choose which View to render. So there's a few tests right there:
When I call my controller method with given arguments (ShowSalesmanDetail(5))
It should pick the correct View to render ('ShowSalesmanDetail')
It should construct the ViewModel that I expect (A Salesman object with some Sales)
In theory, at this point you don't care how the controller constructs the model, only that it does. In practice though you do need to care, because the controller has dependencies (the big one being the database), which you need to cater for. You've chosen to abstract this with a Repository class that talks to an ORM, but that shouldn't impact the purpose of your tests (though it will definitely alter how you implement those tests).
Ideally the Salesman object in your example would be a regular class, with no dependencies of its own. This way, your repository can construct a Salesman object by populating it from the database/ORM, and your unit tests can also use Salesman objects that you've populated yourself with test data. You shouldn't need to mock your models or data classes.
My personal preference is that you don't take your 'data entities' (what you get back from your ORM) and put them into Views. I would construct a ViewModel class that is tied to one View, and then map from your data entities to your ViewModel. In your example, you might have a Salesman class which represents the data in the database, then a SalesmanModel which represents the information you are displaying on the page (which is usually a subset of what's in the db).
So you might end up with a unit test looking something like this:
public void CallingShowSalesmanShouldReturnAValidModel()
{
ISalesmanRepository repository = A.Fake<ISalesmanRepository>();
SalesmanController controller = new SalesmanController(repository);
const int salesmanId = 5;
Salesman salesman = new Salesman
{
Id = salesmanId,
Name = "Joe Bloggs",
Address = "123 Sesame Street",
Sales = new[]
{
new Sale { OrderId = 123, SaleDate = DateTime.Now.AddMonths(-1) }
}
};
A.CallTo(() => repository.Find(salesmanId)).Returns(salesman);
ViewResult result = controller.ShowSalesman(salesmanId) as ViewResult;
SalesmanModel model = result.Model as SalesmanModel;
Assert.AreEqual(salesman.Id, model.Id);
Assert.AreEqual(salesman.Name, model.Name);
SaleModel saleModel = model.Sales.First();
Assert.AreEqual(salesman.Sales.First().OrderId, saleModel.OrderId);
}
This test is by no means ideal but hopefully gives you an idea of the structure. For reference, the A.Fake<> and A.CallTo() stuff is from FakeItEasy, you could replace that with your mocking framework of choice.
If you were doing proper TDD, you wouldn't have started with the Repository - you'd have written your Controller tests, probably got them passing, and then realised that having all this ORM/DB code in the controller is a bad thing, and refactored it out. The same approach should be taken for the Repository itself and so on down the dependency chain, until you run out of things that you can mock (the ORM layer most likely).

Why is Entity Manager clear() required? - Spring3 #Transactional, JPA2/Hibernate3

I have a JSF2 application that is using JPA2/Hibernate with Spring #Transactional. There are no #Transactional statements in the UI (backing beans), only in the service layer. (I am using #Transactional(propagation=Propagation.MANDATORY) in the DAOs to ensure every call occurs in a transaction.) It's all works very nicely, except...
When I am opening and updating the entities through the transactional service methods, Sometimes the retrieved entities are old. It doesn't matter that it's the same user in the same session, occasionally, the JPA "read" methods return older stale entities that have (should have) already been replaced. This stumped me for quite a while, but it turns out it is caused by caching in the Entity Manager. The DAOs are annotated with #Repository, so the injected EntityManager is being reused. I had expected that when the transaction completed, the entity manager would automatically be cleared. But that is not the case. Usually the Entity Manager returns the correct value, but often it reaches back and returns an old one from an earlier transaction instead.
As a workaround, I have sprinkled strategic entityManager.clear() statements in the DAO read methods, but that is ugly. The entityManagers should be cleared after each transaction.
Has anyone experienced this? Is there a proper solution? Can the entity manager be cleared after each transaction?
Thanks very much.
I am using: org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean and org.springframework.orm.jpa.JpaTransactionManager
The #Transactional annotation exists in the service layer. The service methods marked with #Transactional will adhere to the ACID properties no matter how many DAO calls are made from within it.
This means that you need not annotate the DAO methods as #Transactional.
I am working on something similar and this is how I have done it and my data is consistent.
Try it this and see if you are still getting inconsistent data.
Do you use #PersistenceContext annotation (above EntityManager in DAO) combined with PersistenceAnnotationBeanPostProcessor bean (you don't have to define PersistenceAnnotationBeanPostProcessor bean if you are using <context:annotation-config/> and <context:component-scan/> XML tags) ? If not, I guess this is the reason of your problems.

TDD behavior testing with no getters/setters

I'm applying TDD to my first event centric project (CQRS, Event sourcing etc) and I'm writing my tests according to Greg Young's simple testing framework Given, When, Expect. My test fixture takes a command, commandhandler and aggregate root and then tests the events outputted.
CommandTestFixture<TCommand, TCommandHandler, TAggregateRoot>
For example here is a typical test
[TestFixture]
public class When_moving_a_group :
CommandTestFixture<MoveGroup, MoveGroupHandler, Foo>
I am very happy with these tests on the whole but with the the above test I've hit a problem. The aggregate root contains a collection of groups. The command MoveGroup reorders the collection, taking a from & to index. I setup the test and asserted that the correct GroupMoved event was generated with the correct data.
As an additional test I need to assert that the reordering of the Groups collection actually took place correctly? How do I do this when the aggregate root has no public getters/setters. I could add a method to retrieve the group at a particular index but isn't this breaking encapsulation simply to be testable?
What's the correct way to go about this?
EDIT
The reordering of the groups takes place in the GroupMoved handler on the Aggregate root.
private void Apply(GroupMoved e)
{
var moved = groups[e.From];
groups.RemoveAt(e.From);
groups.Insert(e.To, moved);
}
The friction here comes because you want to assert something about the internal implementation, but what you have at hand is at the top level.
Your tests and assertions need to be at the same logical level. There are two ways to re-arrange this:
What effect does re-ordering groups have on subsequent commands or queries which you do have at the top level?
This should give you an avenue for asserting that the correct outcome occurs without needing to assert anything about the ordering of the groups directly. This keeps the test at the top level and would allow all sorts of internal refactoring (e.g. perhaps lazy sorting of the groups).
Can you test at a lower level?
If you feel that testing as described above is too complicated, you might want to frame your test at a more detailed level. I think of this like focusing in on a section of detail to get it right.
Down at this level (rather than your composite root), the interfaces will know about groups and you'll have the opportunity to assert what you want to assert.
Alternatively, do you need this test at all?
If you can not find a suitable test at either of the above levels, then are you sure you need this test at all? If there is no visible external difference then there is no need to lock the behaviour in place with a test.

unit testing a factory method

suppose I have several OrderProcessors, each of them handles an order a little differently.
The decision about which OrderProcessor to use is done according to the properties of the Order object, and is done by a factory method, like so:
public IOrderProcessor CreateOrderProcessor(IOrdersRepository repository, Order order, DiscountPercentages discountPercentages)
{
if (order.Amount > 5 && order.Unit.Price < 8)
{
return new DiscountOrderProcessor(repository, order, discountPercentages.FullDiscountPercentage);
}
if (order.Amount < 5)
{
// Offer a more modest discount
return new DiscountOrderProcessor(repository, order, discountPercentages.ModestDiscountPercentage);
}
return new OutrageousPriceOrderProcessor(repository, order);
}
Now, my problem is that I want to verify that the returned OrderProcessor has received the correct parameters (for example- the correct discount percentage).
However, those properties are not public on the OrderProcessor entities.
How would you suggest I handle this scenario?
The only solution I was able to come up with is making the discount percentage property of the OrderProcessors public, but it seems like an overkill to do that just for the purpose of unit testing...
One way around this is to change the fields you want to test to internal instead of private and then set the project's internals visible to the testing project. You can read about this here: http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx
You would do something like this in your AssemblyInfo.cs file:
[assembly:InternalsVisibleTo("Orders.Tests")]
Although you could argue that your unit tests should not necessarily care about the private fields of you class. Maybe it's better to pass in the values to the factory method and write unit tests for the expected result when some method (assuming Calculate() or something similar) is called on the interface.
Or another approach would be to unit test the concrete types (DiscountOrderProcessor, etc.) and confirm their return values from the public methods/properties. Then write unit tests for the factory method that it correctly returns the correct type of interface implementation.
These are the approaches I usually take when writing similar code, however there are many different ways to tackle a problem like this. I would recommend figuring out where you would get the most value in unit tests and write according to that.
If discount percentage is not public, then it's not part of the IOrderProcessor contract and therefore doesn't need to be verified. Just have a set of unit tests for the DiscountOrderProcessor to verify it's properly computing your discounts based on the discount percent passed in via the constructor.
You have a couple of choices as I see it. you could create specializations of DiscountOrderProcessor :
public class FullDiscountOrderProcessor : DiscountOrderProcessor
{
public FullDiscountOrderProcessor(IOrdersRepository repository, Order order):base(repository,order,discountPercentages.FullDiscountPercentage)
{}
}
public class ModestDiscountOrderProcessor : DiscountOrderProcessor
{
public ModestDiscountOrderProcessor (IOrdersRepository repository, Order order):base(repository,order,discountPercentages.ModestDiscountPercentage)
{}
}
and check for the correct type returned.
you could pass in a factory for creating the DiscountOrderProcessor which just takes an amount, then you could check this was called with the correct params.
You could provide a virtual method to create the DiscountOrderProcessor and check that is called with the correct params.
I quite like the first option personally, but all of these approaches suffer from the same problem that in the end you can't check the actual value and so someone could change your discount amounts and you wouldn't know. Even wioth the first approach you'd end up not being able to test what the value applied to FullDiscountOrderProcessor was.
You need to have someway to check the actual values which leaves you with:
you could make the properties public (or internal - using InternalsVisibleTo) so you can interrogate them.
you could take the returned object and check that it correctly applies the discount to some object which you pass in to it.
Personally I'd go for making the properties internal, but it depends on how the objects interact and if passing a mock object in to the discount order processor and verifying that it is acted on correctly is simple then this might be a better solution.

Testing Mongoose Node.JS app

I'm trying to write unit tests for parts of my Node app. I'm using Mongoose for my ORM.
I've searched a bunch for how to do testing with Mongoose and Node but not come with anything. The solutions/frameworks all seem to be full-stack or make no mention of mocking stuff.
Is there a way I can mock my Mongoose DB so I can return static data in my tests? I'd rather not have to set up a test DB and fill it with data for every unit test.
Has anyone else encountered this?
I too went looking for answers, and ended up here. This is what I did:
I started off using mockery to mock out the module that my models were in. An then creating my own mock module with each model hanging off it as a property. These properties wrapped the real models (so that child properties exist for the code under test). And then I override the methods I want to manipulate for the test like save. This had the advantage of mockery being able to undo the mocking.
but...
I don't really care enough about undoing the mocking to write wrapper properties for every model. So now I just require my module and override the functions I want to manipulate. I will probably run tests in separate processes if it becomes an issue.
In the arrange part of my tests:
// mock out database saves
var db = require("../../schema");
db.Model1.prototype.save = function(callback) {
console.log("in the mock");
callback();
};
db.Model2.prototype.save = function(callback) {
console.log("in the mock");
callback("mock staged an error for testing purposes");
};
I solved this by structuring my code a little. I'm keeping all my mongoose-related stuff in separate classes with APIs like "save", "find", "delete" and no other class does direct access to the database. Then I simply mock those in tests that rely on data.
I did something similar with the actual objects that are returned. For every model I have in mongoose, I have a corresponding class that wraps it and provides access-methods to fields. Those are also easily mocked.
Also worth mentioning:
mockgoose - In-memory DB that mocks Mongoose, for testing purposes.
monckoose - Similar, but takes a different approach (Implements a fake driver). Monckoose seems to be unpublished as of March 2015.