示例#1
0
        public void WhenUsingSharedDatabaseAndMigrator_ShouldOnlyMigrateTheFirstTime()
        {
            using (var db = new TempDBLocalDb())
            {
                var sql = ENTITY_PERSISTENCE_CONTEXT_SQL;
                EntityPersistenceTester.CreateFor <SomeEntityWithDecimalValue>()
                .WithContext <EntityPersistenceContext>()
                .WithDbMigrator(cs => new DbSchemaImporter(cs, sql))
                .WithSharedDatabase(db)
                .ShouldPersistAndRecall();

                // need to clear for the test to work again
                using (var ctx = new EntityPersistenceContext(db.CreateConnection()))
                {
                    ctx.EntitiesWithDecimalValues.Clear();
                    ctx.SaveChangesWithErrorReporting();
                }

                Assert.DoesNotThrow(() =>
                {
                    EntityPersistenceTester.CreateFor <SomeEntityWithDecimalValue>()
                    .WithContext <EntityPersistenceContext>()
                    .WithDbMigrator(cs => new DbSchemaImporter(cs, sql))
                    .WithSharedDatabase(db)
                    .ShouldPersistAndRecall();
                });
            }
        }
示例#2
0
        public void Tester_ShouldBeAbleToShareATempDb()
        {
            //---------------Set up test pack-------------------
            var tempDb = new TempDbWithCallInformation();

            using (new AutoResetter(() => { }, () => tempDb.Dispose()))
            {
                //---------------Assert Precondition----------------

                //---------------Execute Test ----------------------
                EntityPersistenceTester.CreateFor <COMBlockListReason>()
                .WithContext <CommunicatorContext>()
                .WithSharedDatabase(tempDb)
                .WithDbMigrator(connectionString => new DbSchemaImporter(connectionString, TestResources.dbscript))
                .ShouldPersistAndRecall();
                Assert.AreEqual(0, tempDb.DisposeCalls);
                using (var ctx = new CommunicatorContext(tempDb.CreateConnection()))
                {
                    ctx.BlockListReasons.Clear(); // required to allow the persistence test to complete
                    ctx.SaveChangesWithErrorReporting();
                }
                EntityPersistenceTester.CreateFor <COMBlockListReason>()
                .WithContext <CommunicatorContext>()
                .WithSharedDatabase(tempDb)
                .WithDbMigrator(connectionString => new DbSchemaImporter(connectionString, TestResources.dbscript))
                .ShouldPersistAndRecall();

                //---------------Test Result -----------------------
                Assert.AreEqual(0, tempDb.DisposeCalls);
            }
        }
示例#3
0
        public void Tester_WithoutAfterPersisting_ShouldWorkTheSame()
        {
            //---------------Set up test pack-------------------
            var beforePersistingCalled = false;

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            EntityPersistenceTester.CreateFor <COMBlockListReason>()
            .WithContext <CommunicatorContext>()
            .WithCollection(ctx => ctx.BlockListReasons)
            .WithBuilder <ComBlockListReasonBuilder>()
            .WithDbMigrator(connectionString => new DbSchemaImporter(connectionString, TestResources.dbscript))
            .BeforePersisting((ctx, entity) =>
            {
                beforePersistingCalled = true;
                Assert.IsNotNull(ctx);
                Assert.IsInstanceOf <CommunicatorContext>(ctx);
                Assert.IsNotNull(entity);
                Assert.IsInstanceOf <COMBlockListReason>(entity);
            })
            .ShouldPersistAndRecall();

            //---------------Test Result -----------------------
            Assert.IsTrue(beforePersistingCalled);
        }
示例#4
0
        public void Tester_WithoutBeforePersisting_ShouldWorkTheSame()
        {
            //---------------Set up test pack-------------------
            var afterPersistingCalled = false;

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            EntityPersistenceTester.CreateFor <COMBlockListReason>()
            .WithContext <CommunicatorContext>()
            .WithBuilder <ComBlockListReasonBuilder>()
            .WithDbMigrator(connectionString => new DbSchemaImporter(connectionString, TestResources.dbscript))
            .AfterPersisting((before, after) =>
            {
                afterPersistingCalled = true;
                Assert.IsNotNull(before);
                Assert.IsNotNull(after);
                Assert.AreNotEqual(before, after);
                before.GetType().ShouldBeAssignableFrom <COMBlockListReason>();
            })
            .ShouldPersistAndRecall();

            //---------------Test Result -----------------------
            Assert.IsTrue(afterPersistingCalled);
        }
 public void EmailAttachment_ShouldBeAbleToPersistAndRecall()
 {
     EntityPersistenceTester.CreateFor <EmailAttachment>()
     .WithContext <EmailContext>()
     .WithDbMigrator(MigratorFactory)
     .WithSharedDatabase(_sharedTempDb)
     .WithAllowedDateTimePropertyDelta(_oneSecond)
     .ShouldPersistAndRecall();
 }
        public void WithAllowedDateTimeDelta_GivenDelta_WhenDeltaIsExceeded_ShouldThrow()
        {
            // Pre-amble: I've noticed that, periodically, a test against an entity
            //  with a DateTime field will fail: the persisted entity will come back
            //  with the field different by one (rarely two) milliseconds. Mostly,
            //  in production, timestamps are only used to seconds precision, so mostly,
            //  we don't actually care. The point of this test is to fail on the few that do
            //  when we're not catering for the delta. The plan is:
            //  1) add a WithAllowedDateTimeDelta method which takes a timespan
            //          - so the consumer can specify exactly how fine to make the
            //              allowance
            //  2) default to using an allowed delta which covers the observed test flops (so
            //      probably 2 ms)
            //---------------Set up test pack-------------------

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            var exceptions = new List <Exception>();

            using (new TestExecutionContext.IsolatedContext())
            {
                var attempts = 0;
                while (attempts++ < 10)
                {
                    Parallel.For(
                        0,
                        4,
                        (i, state) =>
                    {
                        // at least one of these should hit the issue
                        try
                        {
                            EntityPersistenceTester.CreateFor <SomeEntityWithDateTimeValue>()
                            .WithContext <ContextForDateTimeDeltaTesting>()
                            .WithAllowedDateTimePropertyDelta(
                                new TimeSpan(0, 0, 0, 0, 1))         // there should be at least one 2ms delta
                            .SuppressMissingMigratorMessage()
                            .ShouldPersistAndRecall();
                        }
                        catch (Exception ex)
                        {
                            state.Stop();
                            exceptions.Add(ex);
                        }
                    });
                    if (exceptions.Any())
                    {
                        break;
                    }
                }
            }

            //---------------Test Result -----------------------
            CollectionAssert.IsNotEmpty(exceptions);
        }
示例#7
0
        public void CreateFor_ShouldReturnEntityPersistenceTester()
        {
            //---------------Set up test pack-------------------

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            var result = EntityPersistenceTester.CreateFor <COMBlockListReason>();

            //---------------Test Result -----------------------
            Assert.IsNotNull(result);
            Assert.IsInstanceOf <EntityPersistenceTesterFor <COMBlockListReason> >(result);
        }
示例#8
0
        public void ActingOnEntitiesWithTracking()
        {
            //---------------Set up test pack-------------------

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            EntityPersistenceTester.CreateFor <SomeEntityWithDecimalValue>()
            .WithContext <EntityPersistenceContext>()
            .WithDbMigrator(s => new DbSchemaImporter(s, TestResources.entitypersistence))
            .ShouldPersistAndRecall();

            //---------------Test Result -----------------------
        }
示例#9
0
        public void ShortestPossibleUsefulUsage_CoversSimplestCases()
        {
            //---------------Set up test pack-------------------

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            EntityPersistenceTester.CreateFor <COMBlockList>()
            .WithContext <CommunicatorContext>()
            .WithDbMigrator(s => new DbSchemaImporter(s, TestResources.dbscript))
            .ShouldPersistAndRecall();

            //---------------Test Result -----------------------
        }
示例#10
0
 public void LoanItem_ShouldBeAbleToPersistAndRecall()
 {
     //---------------Set up test pack-------------------
     //---------------Assert Precondition----------------
     //---------------Execute Test ----------------------
     using (var ctx = new WimsDbContext(_tempDb.CreateConnection()))
         Clear(ctx);
     EntityPersistenceTester.CreateFor <LoanItem>()
     .WithContext <WimsDbContext>()
     .WithSharedDatabase(_tempDb)
     .WithEntityFrameworkLogger(Console.WriteLine)
     .WithDbMigrator(conn => new MigrationsRunner(conn))
     .ShouldPersistAndRecall();
     //---------------Test Result -----------------------
 }
示例#11
0
        public void SomeChildEntity_ShouldBeAbleToPersistAndRecall()
        {
            // this is a more fluent approach to the same test above
            //---------------Set up test pack-------------------

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            //  option 1: spin up a clean db every time and migrate
            EntityPersistenceTester.CreateFor <SomeChildEntity>()
            .WithContext <SomeContext>()
            // totally optional: the test helper will search for an existing builder or
            //  create one on the fly (which would be re-used the next time someone needs one)
            .WithBuilder <SomeChildEntityBuilder>()
            .WithDbMigrator(connectionString => new CompositeDBMigrator(connectionString, true))
            // optional: the tester can figure this out
            .WithCollection(ctx => ctx.SomeChildEntities)
            .BeforePersisting((ctx, entity) =>
            {
                Assert.IsNotNull(entity.SomeEntity);
            })
            .AfterPersisting((entityBefore, entityAfter) =>
            {
                // no assertions done here in this test, but this is where you would
                //  do custom assertions
            })
            // totally optional: the default is for the tester to ignore virtual properties (ie, navigation properties)
            .WithIgnoredProperties(typeof(SomeChildEntity).VirtualProperties())
            // also optional: how much drift to allow for datetime property persistence
            //  the amount which makes sense depends on your backing field's resolution
            //  - the default behaviour allows just enough difference for most sql server implementations
            .WithAllowedDateTimePropertyDelta(TimeSpan.FromMilliseconds(100))
            .ShouldPersistAndRecall();

            // option 2: using the shared database from the base context
            //              - which requires:
            //                  [OneTimeSetup] should call Configure and perform migrations
            //                  [SetUp] should clear out the context to avoid collisions with the tester
            EntityPersistenceTester.CreateFor <SomeChildEntity>()
            .WithContext <SomeContext>()
            .WithSharedDatabase(_tempDb)
            .BeforePersisting((ctx, entity) =>
            {
                Assert.IsNotNull(entity.SomeEntity);
            })
            .ShouldPersistAndRecall();
            //---------------Test Result -----------------------
        }
示例#12
0
        public void Tester_WithoutAnyUserSetupOrValidation_ShouldWorkTheSame()
        {
            //---------------Set up test pack-------------------

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            EntityPersistenceTester.CreateFor <COMBlockListReason>()
            .WithContext <CommunicatorContext>()
            .WithCollection(ctx => ctx.BlockListReasons)
            .WithBuilder <ComBlockListReasonBuilder>()
            .WithDbMigrator(connectionString => new DbSchemaImporter(connectionString, TestResources.dbscript))
            .ShouldPersistAndRecall();

            //---------------Test Result -----------------------
        }
示例#13
0
        public void Tester_ShouldBeAbleToBeGivenAFuncToCreateTheTempDb()
        {
            //---------------Set up test pack-------------------
            var beforePersistingCalled = false;
            var afterPersistingCalled  = false;
            var tempDb = new TempDbWithCallInformation();

            using (new AutoResetter(() => { }, () => tempDb.ActualDispose()))
            {
                Assert.AreEqual(0, tempDb.DisposeCalls);

                //---------------Assert Precondition----------------

                //---------------Execute Test ----------------------
                EntityPersistenceTester.CreateFor <COMBlockListReason>()
                .WithContext <CommunicatorContext>()
                .WithTempDbFactory(() => tempDb)
                .WithDbMigrator(connectionString => new DbSchemaImporter(connectionString, TestResources.dbscript))
                .BeforePersisting((ctx, entity) =>
                {
                    beforePersistingCalled = true;
                    Assert.IsNotNull(ctx);
                    Assert.IsInstanceOf <CommunicatorContext>(ctx);
                    Assert.IsNotNull(entity);
                    Assert.IsInstanceOf <COMBlockListReason>(entity);
                })
                .AfterPersisting((before, after) =>
                {
                    afterPersistingCalled = true;
                    Assert.IsNotNull(before);
                    Assert.IsNotNull(after);
                    Assert.AreNotEqual(before, after);
                    before.GetType().ShouldBeAssignableFrom <COMBlockListReason>();
                })
                .ShouldPersistAndRecall();

                //---------------Test Result -----------------------
                Assert.IsTrue(beforePersistingCalled);
                Assert.IsTrue(afterPersistingCalled);
                Assert.AreEqual(1, tempDb.DisposeCalls);

                // test that the provided tempdb was actually used
                AssertHasTable(tempDb, "COMBlockListReason");
                AssertTableIsNotEmpty(tempDb, "COMBlockListReason");
            }
        }
示例#14
0
        public void SuppressMissingMigratorMessage_ShouldSuppressMissingMigratorMessage()
        {
            //---------------Set up test pack-------------------
            string logMessage = null;

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            EntityPersistenceTester.CreateFor <COMBlockListReason>()
            .WithContext <CommunicatorContext>()
            .WithLogAction(s => logMessage = s)
            .SuppressMissingMigratorMessage()
            .ShouldPersistAndRecall();

            //---------------Test Result -----------------------
            Assert.IsNull(logMessage);
        }
示例#15
0
        public void UsingDefaultDeltaOf2Ms_ShouldAllowTestItemDateTimePropertyValuesToDifferByThatDelta()
        {
            // Pre-amble: I've noticed that, periodically, a test against an entity
            //  with a DateTime field will fail: the persisted entity will come back
            //  with the field different by one (rarely two) milliseconds. Mostly,
            //  in production, timestamps are only used to seconds precision, so mostly,
            //  we don't actually care. The point of this test is to fail on the few that do
            //  when we're not catering for the delta. The plan is:
            //  1) add a WithAllowedDateTimeDelta method which takes a timespan
            //          - so the consumer can specify exactly how fine to make the
            //              allowance
            //  2) default to using an allowed delta which covers the observed test flops (so
            //      probably 2 ms)
            //---------------Set up test pack-------------------

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            var exceptions = new List <Exception>();

            Parallel.For(0, 5, (i, state) =>
            {
                // at least one of these should hit the issue
                try
                {
                    EntityPersistenceTester.CreateFor <SomeEntityWithDateTimeValue>()
                    .WithContext <ContextForDateTimeDeltaTesting>()
                    .SuppressMissingMigratorMessage()
                    .ShouldPersistAndRecall();
                }
                catch (Exception ex)
                {
                    state.Stop();
                    exceptions.Add(ex);
                }
            });

            //---------------Test Result -----------------------
            if (exceptions.Any())
            {
                exceptions.ForEach(e => Console.WriteLine(e.Message));
            }
            CollectionAssert.IsEmpty(exceptions);
        }
示例#16
0
        public void WhenNoMigratorAndNoSuppressMissingMigratorMessage_ShouldWarnAboutMigrator()
        {
            //---------------Set up test pack-------------------
            string logMessage = null;

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            EntityPersistenceTester.CreateFor <COMBlockListReason>()
            .WithContext <CommunicatorContext>()
            .WithLogAction(s => logMessage = s)
            .ShouldPersistAndRecall();

            //---------------Test Result -----------------------
            Assert.IsNotNull(logMessage);
            StringAssert.Contains("warning", logMessage.ToLower(CultureInfo.InvariantCulture));
            StringAssert.Contains("entityframework will perform migrations", logMessage.ToLower(CultureInfo.InvariantCulture));
            StringAssert.Contains("to suppress this message", logMessage.ToLower(CultureInfo.InvariantCulture));
        }
示例#17
0
        public void WithEntityFrameworkLogger_ShouldLogUsingProvidedAction()
        {
            //---------------Set up test pack-------------------
            var logLines = new List <string>();

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            EntityPersistenceTester.CreateFor <COMBlockList>()
            .WithContext <CommunicatorContext>()
            .WithEntityFrameworkLogger(logLines.Add)
            .WithDbMigrator(s => new DbSchemaImporter(s, TestResources.dbscript))
            .ShouldPersistAndRecall();

            //---------------Test Result -----------------------
            CollectionAssert.IsNotEmpty(logLines);
            var total = string.Join("\n", logLines).ToLower(CultureInfo.InvariantCulture);

            StringAssert.Contains("insert", total);
            StringAssert.Contains("select", total);
            StringAssert.Contains("comblocklist", total);
        }
示例#18
0
        public void ShouldCallAllBeforeAndAfterPersistingBlocks_InRegistrationOrder()
        {
            //--------------- Arrange -------------------
            var allCalls = 0;

            //--------------- Assume ----------------

            //--------------- Act ----------------------
            EntityPersistenceTester.CreateFor <SomeEntityWithDecimalValue>()
            .WithContext <EntityPersistenceContext>()
            .WithDbMigrator(s => new DbSchemaImporter(s, TestResources.entitypersistence))
            .BeforePersisting((ctx, entity) =>
            {
                entity.DecimalValue = 1;
                allCalls++;
            })
            .BeforePersisting((ctx, entity) =>
            {
                Assert.AreEqual(1, entity.DecimalValue);
                entity.DecimalValue = 2;
                allCalls++;
            })
            .AfterPersisting((before, after) =>
            {
                Assert.AreEqual(2, after.DecimalValue);
                after.DecimalValue = 3;
                allCalls++;
            })
            .AfterPersisting((before, after) =>
            {
                Assert.AreEqual(after.DecimalValue, 3);
                allCalls++;
            })
            .ShouldPersistAndRecall();

            //--------------- Assert -----------------------
            Assert.AreEqual(4, allCalls);
        }
示例#19
0
        public void Tester_WithAllPriorProvidedStuffs_ShouldWorkTheSame()
        {
            //---------------Set up test pack-------------------
            var beforePersistingCalled = false;
            var afterPersistingCalled  = false;

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            EntityPersistenceTester.CreateFor <COMBlockListReason>()
            .WithContext <CommunicatorContext>()
            .WithCollection(ctx => ctx.BlockListReasons)
            .WithBuilder <ComBlockListReasonBuilder>()
            .WithIgnoredProperties("COMBlockListReasonID")      // not actually required
            .WithDbMigrator(connectionString => new DbSchemaImporter(connectionString, TestResources.dbscript))
            .BeforePersisting((ctx, entity) =>
            {
                beforePersistingCalled = true;
                Assert.IsNotNull(ctx);
                Assert.IsInstanceOf <CommunicatorContext>(ctx);
                Assert.IsNotNull(entity);
                Assert.IsInstanceOf <COMBlockListReason>(entity);
            })
            .AfterPersisting((before, after) =>
            {
                afterPersistingCalled = true;
                Assert.IsNotNull(before);
                Assert.IsNotNull(after);
                Assert.AreNotEqual(before, after);
                before.GetType().ShouldBeAssignableFrom <COMBlockListReason>();
            })
            .ShouldPersistAndRecall();

            //---------------Test Result -----------------------
            Assert.IsTrue(beforePersistingCalled);
            Assert.IsTrue(afterPersistingCalled);
        }
示例#20
0
        public void WhenMigrationsCreateEntitiesButRunBeforeClearsThemOut_ShouldNotFailBecauseOfExistingEntities()
        {
            //---------------Set up test pack-------------------
            using (var db = new TempDBLocalDb())
            {
                //---------------Assert Precondition----------------

                //---------------Execute Test ----------------------
                Assert.DoesNotThrow(() =>
                                    EntityPersistenceTester.CreateFor <SomeEntityWithDecimalValue>()
                                    .WithContext <EntityPersistenceContext>()
                                    .WithDbMigrator(cs => new DbSchemaImporter(cs, ENTITY_PERSISTENCE_CONTEXT_WITH_DATA_SQL))
                                    .WithSharedDatabase(db)
                                    .BeforePersisting((ctx, entity) =>
                {
                    ctx.EntitiesWithDecimalValues.Clear();
                    ctx.SaveChangesWithErrorReporting();
                })
                                    .ShouldPersistAndRecall()
                                    );

                //---------------Test Result -----------------------
            }
        }