How to unit test an entity is targeting the correct DBMS table - jpa

I have the following entity and it was not until run time that i realized that the table name annotation is incorrect.
How can i write unit tests to prevent this?
#Entity
#Table(name = "cache_server")
public class VirtualMachine implements Serializable {
}

It is not about unit testing here, but rather about integration testing, as you need a JPA provider to test it (with a DB server). And when it comes to integration tests, it is very specific to what technologies you use. If you are in Application Server, like Jboss, take a look at Arquillian.
UPDATE
Although I think that usually you do not want to unit test values in annotations, as they represent configuration data, you can always read the values in the annotations using some reflexion. See this question (directly in the question) for an example.

Related

DataSource in Microsoft Test for Entity Framework

I'm creating some test using ms test for an already written routine that use entity framework, and I would like to use the [DataSource] attribute to generate a test routine for a set of data in the database.
My problem is that I can just select a Table and load the single fields in the test, but I would like to fetch directly a set ob ef entities and process directly in the test routine, in a way much more similar to the way the code to test is wrote.
Exist some kind of [EFDatasource] that let me express a Ef query as datasource and use the entity in the test?
thanks,
luca
You should just use a context instance (or service/repository, what have you) in your unit test method and get the entities from it. You can supply the connection string in a config file in the unit test project. This way the test methods will be totally relieved from any connection worries. They just instantiate objects and work with them.
Some will probably comment that this is not unit testing but integration testing and that you should mock the EF context, but that is virtually impossible. Testing EF should be done with... EF.

When I do not expose IQueryable then I have not to do integration tests

I have read lots of SO links about unit/integration testing of the entity framework and to sum it all up if I have not misunderstood:
When the repository interface exposes an IQueryable I have to do integration tests (unit tests are not sufficient) because the IQueryable which is linq to entities can be turned into a linq to objects query which can behave totally different which can only be tested having a real database.
When the repository interface exposes only IEnumerable or List it is enough to unit test the repository.
I know it can be very cool to compose an IQueryable in my service without adding many new interface methods...
But if the above is true and I want to avoid integration tests if possible...
What do you think?
When the repository interface exposes only IEnumerable or List it is
enough to unit test the repository.
No. That is misunderstanding. When repository exposes only IEnumerable or List it is safe to fake or mock it and unit test the logic using your repository. The repository itself must be still covered with integration tests because it defines database queries which must be tested against the real database.
The main reason to hide the query behind the repository is to separate concerns and define strict boundary between application logic and database executed logic (the query). Each logic requires its own tests.
Questions you are referring most probably discussed mocking or faking the EF context / EF sets or repository exposing IQueryable. In such case the repository exposes database executed logic into upper layer which makes correct testing much harder. In such case you need to unit test your application logic and somehow fake Linq-to-entities (database logic) with Linq-to-objects. But such tests are not enough to test those queries so you also need integration tests which will duplicate part of your unit tests.

How can I do TDD and Unit Testing for EF Code First entity declaration and mapping?

I have am about to retro-code a suite of unit tests for a new MVC4 app. Because nearly all my code in the EF data project is copied straight from code generated by the VS2012 EF Reverse Engineering tool, I have decided to skip unit tests in this part of the application, unless I can somehow automatically generate them. I have no business logic at here and I would like to first concentrate my efforts on ensuring better QA on the business side. But, I would like to know how one goes about first TDD, and second, just unit testing in general here.
Let's assume I don't have to or want to mock the database yet. I have often been quite happy unit testing against a test DB copy before, but with more conventional, home rolled ORM.
So, do I start with a test that instantiates my drived DbContext, then derive a DbContext until that test passes. Then, test for instantiating an entity, and create an entity, going on to test for a DbSet of those entities, which test will also include checking if the table is created. All is still good and well, if not bloody laborious, but my head asplode as soon as I start thinking of even a hint of testing my fluent mapping classes for all my entities. What now?
Testing against database is not unit testing - it is integration testing and integration testing usually doesn't follow the granularity of unit testing. Why it is not unit testing? Because unit testing tests single self contained unit - all external dependencies are faked. When your test spans both your unit code and database it test dependency as well = it is integration test.
All EF dependent code should be tested with integration testing. It doesn't make sense to unit test Microsoft's code. For example your question about mapping. Correct unit test for mapping does something like:
Preparation: Prepare compiled model with your entity mapping configuration
Execution: Create DbContext from compiled model and get metadata workspace from the context
Validation: Assert that metadata context contains your mapped entity
Now you can repeat similar test for every property you want to map in that entity.
That is obviously framework code which should already work - these tests should be done by people developing the framework.
In your case simple make integration test against local database which will try to load, save, update and delete entity and assert expectations you have on these operations. If anything in mapping is wrong at least one of these tests will fail.

How to manage test data for Hibernate Search integration tests

I have a Spring-based system that uses Hibernate Search 3.4 (on top of Hibernate 3.5.4). Integration tests are managed by Spring, with #Transactional annotation. At the moment test data (entities that are to be indexed) is loaded by Liquibase script, we use it's Spring integration. It's very inconvenient to manage.
My new solution is to have test data defined as Spring beans and wire them as Resources, by name. This part works.
I tried to have these beans persisted and indexed in setUp method of my test cases (and in test methods themselves) but I failed. They get into DB fine but I can't get them indexed. I tried calling index() on FullTextEntityManager (with flushToIndexes), I tried createIndexer().startAndWait().
What else can I do?
Or may be there is some better option of testing HS?
Thank You in advance
My new solution is to have test data defined as Spring beans and wire
them as Resources, by name. This part works.
sounds like a strange setup for a unit test. To be honest I am not quote sure how you do this.
In Search itself an in memory database (H2) is used together with a Lucene RAM directory. The benefits of such a setup is that it is fast and easy to avoid dependencies between tests.
I tried to have these beans persisted and indexed in setUp method of
my test cases (and in test methods themselves) but I failed. They get
into DB fine but I can't get them indexed.
If automatic indexing is enabled and the persisting of the test data is occurring within an transaction, it should work. A common mistake in combination with Spring is to use the wrong transaction manager. The Hibernate Search forum has a lot of threads around this, for example this one - https://forum.hibernate.org/viewtopic.php?f=9&t=998155. Since you are not giving any concrete configuration and code examples it is hard to give more specific advice.
I tried createIndexer().startAndWait()
that is also a good approach. I would recommend this approach if you want to insert not such a couple of test entities, but a whole set of data. In this case it can make sense to use a framework like dbunit to insert the testdata and then manually index the data. createIndexer().startAndWait() is the right tool for that. Extracting all this loading/persisting/indexing functionality into a common test base class is the way to go. The base class can also be responsible to do all the Spring bootstrapping.
Again, to give more specific feedback you have to refine your question.
I have a complete different approach, when I write any queries, i want to write a complete test suite, but data creation has always been pain(special mention to when test customer gets corrupt and all your test suite breaks.
To solve this I created Random-JPA. It's simple and easy to integrate. The whole idea is you create fresh data and test.
You Can find the full documentation here

ObjectContext never derives from an interface?? How do you apply DI/IoC in case of multiple types of ObjectContext?

If you have a system that has multiple types of object contexts. For Eg: BillingObjectContext, HumanResourceObjectContext etc. All derive from ObjectContext but ObjectContext Class does not implement any specific interface like IObjectContext. How would you apply DI/IoC in case of multiple types of ObjectContext say using Ninject?
If you must depend on it in a test, you have to mock it. Here's a sample; it's not much harder than implementing an interface. See also TDD improvements in EF 4.
Why can't we just create the actual context object to be used in our tests? Since we don't want our tests to affect the production database, we can always specify a connection string that points to a test database. Before running each test, construct a new context, add the data you will need in your test, proceed with the unit test, then in the test cleanup section, delete all the records that were created during the test. The only side-affect here would be that the auto-increment IDs would be used up in the test database, but since it's a test database - who cares?
I know that most answers regarding this question propose using DI/IoC designs to create interfaces for data contexts etc. but the reason I am using Entity Framework is exactly to not write any interfaces for my database connections, object models, and simple CRUD transactions. To write mock interfaces for my data objects and to write complex queryable objects to support LINQ, defeats the purpose of relying on highly-tested and reliable Entity Framework.
This pattern for unit testing is not new - Ruby on Rails has been using it for a long time and it's worked out great. Just as .NET provides EF, RoR provides ActiveRecord objects and each unit test creates the objects it needs, proceeds with the tests, and then deletes all the constructed records.
How to specify connection string for test environment? Since all tests are in their own dedicated test project, adding a new App.Config file with a connection string for the test database would suffice.
Just think of how much headache and pain this will save you.
namespace ProjectNamespace
{
[TestClass]
public class UnitTest1
{
private ObjectContext objContext;
[TestInitialize]
public void SetUp()
{
// Create the object context and add all the necessary data records.
}
[TestMethod]
public void TestMethod1()
{
// Runs the tests.
}
[TestCleanup]
public void CleanUp()
{
// Delete created records.
}
}
}