Entity Framework error during unit test - unit-testing

I'm using the entity framework.
In one of my unit tests I have a line like:
this.Set<T>().Add(entity);
On executing that line I get:
System.InvalidOperationException : The model backing the
'InvoiceNewDataContext' context has changed since the database was
created. Either manually delete/update the database, or call
Database.SetInitializer with an IDatabaseInitializer instance. For
example, the DropCreateDatabaseIfModelChanges strategy will
automatically delete and recreate the database, and optionally seed it
with new data.
Well I've actually deleted the database and removed the connection string.
I'm surprised this error is happening on adding as I wouldn't expect it to happen until I saved the data and it discovered there was no database.
In previous projects/solutions I created during unit tests I have been able to add to the context for test purposes without actually calling SaveChanges.
Would anyone know why this would be happening in my latest projects/solutions?

Are you sure it really didn't use database in your previous projects? If you do not specify any connection string it will silently use a default one to SQLExpress database with local .mdf file so make sure that isn't happening now.

Related

Django helper function executed only in single test when PostgreSQL used

Recently I've changed db engine from SQLite to PostgreSQL. I have successfully migrated whole db design to PostgreSQL (just simple makemigaretions, migrate). Once I ran tests some have failed for some unknown reason (errors suggest that some objects were not created). Failure doesn't apply to all tests, just selected few. Everything has been working before.
I'd start investigating what's going on on test-by-test basis, but some bizarre behavior has appeared. Let's say my test is in class MyTestClass and test is called test_do_something and in MyTestClass there are other tests as well.
When I'm running python manage.py test MyTestClass I'm getting info that test_do_something has failed.
When I'm running python manage.py test MyTestClass.test_do_something everything passes.
On SQLite both ways pass.
I'm assuming that setUpTestData() and setUp() methods work same way in SQLite and PostgreSQL. Or they don't?
Any clue why such discrepancy might be happening?
EDIT
I think I've noticed what might be wrong, but I don't understand why. The problem is because my function I've used to call to create object which is later used only once. Which differs from SQLite execution.
What I mean in my test I have something like this:
def create_object(self):
self.client.post(reverse('myurl'), kwargs={'myargs':arg})
def test_mytest1(self):
# Do something
self.create_object()
# Do something
def test_mytest2(self):
# Do something
self.create_object()
# Do something
def test_mytest3(self):
# Do something
self.create_object()
# Do something
Only for one test create_object() will be executed.
I believe I've fond cause of those failures. As a matter of fact it hasn't been an issue with one-time execution of support function as I expected. The problem has been with hardcoded ids I've used for various reasons. It appears that object I've been hoping to see didn't exist.
Let me explain a bit more what I've experienced. E.g. I had test where I've been referring to particular object passing this object id in URL kwargs. Before this operation I've created object and passed id=1 as kwargs, because I assumed that if this is only place within this test and setUp() it will be 1. It appears that with PostgreSQL it's not so clear. It seems that ids are incremented despite DB flush. Which is completely different behavior then SQLite has been providing.
I'd very much appreciate if someone could provide some more detailed answer why is this happening. Is ID counter not zeroed in PostgreSQL on flush? It would look so.

MDS business rule on more then one domain based attribute

I'm stuck with this problem on Master Data Service (MDS).
I have an entity that has two domain based to other two entities.
I created the first business rule with the first domain based and it works perfectly.
But when I try to create a second business rule with the second domain based, an error appears:
200095 : Cannot specify more than one entity in MetadataGet
400003 : The attribute reference is not valid. The attribute was not found.
400003 : The attribute reference is not valid. The attribute was not found.
Obviously the attribute is valid. In fact, if I delete the first business rules, the second one is published correctly.
I think that MDS block a second business rules if you try to apply to a second domain based attribute.
This happened to us as well, and it seems that this error only occurs if a specific set of actions is taken:
We first restored the MDS 2012 database on SQL Server 2017
We upgraded a database using MDS management tool. Mind that the multi-entity business rules work fine now - they return no errors upon saving, can be published and successfully evalueted
We then realized that we are missing some code changes, so we decided to create a full model package using MDSModelDeploy.exe in our old MDS 2012
We deployed that package using MDSModelDeploy deployupdate command. After that the existing multi-entity rules are failing to publish, you are also unable to create new rules based on different entities within one entity. Unfortunately, we have found no fix for it, as there are simpler ways around it.
At this point we took a step back, restored and upgraded the old database once again, and it turned out that the rules worked, so it got to be the package that has broken those. I do not know what your situation was, since when we created a fresh model in SQL 2017 all of the multi-entity based rules worked perfectly, so I am curious to know what steps should be taken to reproduce the error in your case.
The only possible approach I can think of to fix the situation in point 4, would be to create an MDSModelDeploy update package from the corrupted model and another one from a new, healthy model, and then compare how the XMLs of the multi-entity business rules are structured. We did not try this one though, since we found the workaround described previously.

Django TestCase with fixtures causes IntegrityError due to duplicate keys

I'm having trouble moving away from django_nose.FastFixtureTestCase to django.test.TestCase (or even the more conservative django.test.TransactionTestCase). I'm using Django 1.7.11 and I'm testing against Postgres 9.2.
I have a Testcase class that loads three fixtures files. The class contains two tests. If I run each test individually as a single run (manage test test_file:TestClass.test_name), they each work. If I run them together, (manage test test_file:TestClass), I get
IntegrityError: Problem installing fixture '<path>/data.json': Could not load <app>.<Model>(pk=1): duplicate key value violates unique constraint "<app_model_field>_49810fc21046d2e2_uniq"
To me it looks like the db isn't actually getting flushed or rolled back between tests since it only happens when I run the tests in a single run.
I've stepped through the Django code and it looks like they are getting flushed or rolled back -- depending on whether I'm trying TestCase or TransactionTestCase.
(I'm moving away from FastFixtureTestCase because of https://github.com/django-nose/django-nose/issues/220)
What else should I be looking at? This seems like it should be a simple matter and is right within what django.test.TestCase and Django.test.TransactionTestCase are designed for.
Edit:
The test class more or less looks like this:
class MyTest(django.test.TransactionTestCase): # or django.test.TestCase
fixtures = ['data1.json', 'data2.json', 'data3.json']
def test1(self):
return # I simplified it to just this for now.
def test2(self):
return # I simplified it to just this for now.
Update:
I've managed to reproduce this a couple of times with a single test, so I suspect something in the fixture loading code.
One of my basic assumptions was that my db was clean for every TestCase. Tracing into the django core code I found instances where an object (in one case django.contrib.auth.User) already existed.
I temporarily overrode _fixture_setup() to assert the db was clean prior to loading fixtures. The assertion failed.
I was able to narrow the problem down to code that was in a TestCase.setUpClass() instead of TestCase.setUp(), and so the object was leaking out of the test and conflicting with other TestCase fixtures.
What I don't understand completely is I thought that the db was dropped and recreated between TestCases -- but perhaps that is not correct.
Update: Recent version of Django includes setUpTestData() that should be used instead of setUpClass()

neo4j functionality & unit testing - resetting the database

I've created an application in node.js and have Mocha tests to perform automated unit and functionality testing.
I'm now trying to test database functionality, and want the database to be reset between each test for consistency.
Solution 1
Before each test I was running:
MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r
and then populating the database with cyphers queries obtained using the neo4j-shell dump command. However, the problem with this is that those cypher queries utilise the internal neo4j ids to create links between nodes and relationships, and because the delete query above doesn't reset the internal neo4j id counter to 0 it all goes wrong when you try to run it!
Solution 2
I then looked at physically shutting down the neo4j server, removing the database directory and then rebooting it and populating it. This works, but it takes around 15 seconds, which is useless when I've got 200+ unit tests to run!
Solution 3
I've also looked at transactions in order to be able to roll the database back once the test had completed, but it seems that all queries have to go through the transaction endpoint. I don't think this is feasible.
.
Are there any other ways of doing this? I think solution 1 shows the most promise, but it'd mean going through and changing all my exported cypher queries to avoid using the internal neo4j ids.
For example I'd have to change:
create (_113:`User` {`firstname`:"John", `lastname`:"Smith", `uuid`:"f843c210-26e3-11e5-af31-297c662c0848"})
create (_114:`Instrument` {`name`:"Drums", `uuid`:"f84521a0-26e3-11e5-af31-297c662c0848"})
create _113-[:`PLAYS`]->_114
To:
create (_113:`User` {`firstname`:"John", `lastname`:"Smith", `uuid`:"f843c210-26e3-11e5-af31-297c662c0848"})
create (_114:`Instrument` {`name`:"Drums", `uuid`:"f84521a0-26e3-11e5-af31-297c662c0848"})
MATCH (a:User),(b:Instrument) WHERE a.uuid = 'f843c210-26e3-11e5-af31-297c662c0848' AND b.uuid = 'f84521a0-26e3-11e5-af31-297c662c0848' CREATE UNIQUE (a)-[r:`PLAYS`]->(b) RETURN r
Which is a real pain with a large dataset..
Any thoughts?
As FrobberOfBits kindly suggested, have a look at GraphAware RestTest built precisely for your purpose.

Configuring Unitils properties dynamically

I am testing EJB 3.1. I have a situation where I need to start a transaction manually in my test, perform some CRUD operations within it (to create some test data which is still not committed) and then call a method in my bean to which the transaction from my test will be propagated.
By default, while using Unitils DatabaseModule, the transactions are automatically created in the test. I understand that it is possible to change this default configuration by modifying unitils.properties as follows,
DatabaseModule.Transactional.value.default=disabled
My question is: Is there a possibility to change this configuration dynamically in the test method? I do not want the transactions to be disabled "always". By default transactions can be "commit", and when required, I want to dynamically set it to "disabled".
-Thanks.
You could try this: https://stackoverflow.com/a/6561782/411229
Not sure if it will work for transaction configuration, but worth a shot.