예제 #1
0
            public void CanNotPassStringsForTableValueParameter()
            {
                var reader = new Mock <IDataReader>();

                reader.SetupGet(r => r.FieldCount).Returns(0);
                reader.Setup(r => r.Read()).Returns(false);

                var parms = new DataParameterCollection();
                var cmd   = new Mock <IDbCommand>();

                cmd.SetupAllProperties();
                cmd.Setup(c => c.ExecuteReader()).Returns(reader.Object);
                cmd.SetupGet(c => c.Parameters).Returns(parms);

                var ctx = new Mock <IDbConnection>();

                ctx.Setup(c => c.CreateCommand()).Returns(cmd.Object);

                dynamic toTest = new DynamicStoredProcedure(ctx.Object, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Synchronous, true);

                this.Invoking(_ =>
                {
                    toTest.usp_AddPeople(people: new[] { "Foo", "Bar" });
                }).ShouldThrow <NotSupportedException>("because the string type should not be allowed to be used as TVPs")
                .WithMessage("You can not use a string as a Table-Valued Parameter, since you really need to use a class with properties.",
                             "because the message should be helpful");
            }
예제 #2
0
            public void CanPassUnattributedTableValueParameterClass()
            {
                var reader = new Mock <IDataReader>();

                reader.SetupGet(r => r.FieldCount).Returns(0);
                reader.Setup(r => r.Read()).Returns(false);

                var parms = new DataParameterCollection();
                var cmd   = new Mock <IDbCommand>();

                cmd.SetupAllProperties();
                cmd.Setup(c => c.ExecuteReader()).Returns(reader.Object);
                cmd.SetupGet(c => c.Parameters).Returns(parms);
                cmd.Setup(c => c.CreateParameter()).Returns(new SqlParameter());

                var ctx = new Mock <IDbConnection>();

                ctx.Setup(c => c.CreateCommand()).Returns(cmd.Object);

                dynamic toTest = new DynamicStoredProcedure(ctx.Object, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Synchronous, true);

                toTest.usp_AddPeople(people: new[] { "Foo", "Bar" }.Select(s => new Person {
                    FirstName = s
                }));

                var p = parms.OfType <SqlParameter>().Single();

                p.ParameterName.Should().Be("people", "because that was the argument name");
                p.SqlDbType.Should().Be(SqlDbType.Structured, "because it is a table-valued parameter");
                p.TypeName.Should().Be("[dbo].[Person]", "because that is the name of the Class being passed as a TVP");
            }
예제 #3
0
            public void CallAsyncWithSimpleOutValueThrows()
            {
                var ctx = CreatePeople(parms =>
                {
                    var parm = ((IDbDataParameter)parms[0]);
                    Assert.AreEqual(ParameterDirection.Output, parm.Direction, "Not passed as Output");
                    parm.Value = 42M;
                }, "Foo");

                var toTest = new DynamicStoredProcedure(ctx, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Asynchronous, true);

                try
                {
                    GetPeopleShouldThrow(toTest, ParameterDirection.Output).Wait();
                    Assert.Fail("Expected exception not thrown.");
                }
                catch (AggregateException ax)
                {
                    Assert.AreEqual(DynamicStoredProcedure.asyncParameterDirectionError, ax.InnerException.Message);
                }
                catch (NotSupportedException ex)
                {
                    Assert.AreEqual(DynamicStoredProcedure.asyncParameterDirectionError, ex.Message);
                }
            }
예제 #4
0
            public async Task CanConfigureAwait()
#endif
            {
                var lockr = new SemaphoreSlim(0);
                int count = 0;
                var sync  = new Mock <SynchronizationContext>();

                sync.Setup(sc => sc.Post(It.IsAny <SendOrPostCallback>(), It.IsAny <object>()))
                .Callback <SendOrPostCallback, object>((c, o) =>
                {
                    ++count;
                    c(o);
                });

                var oldContext = SynchronizationContext.Current;

                SynchronizationContext.SetSynchronizationContext(sync.Object);

                var     ctx              = CreatePeople(_ => lockr.Wait(TimeSpan.FromMilliseconds(100)), "Foo");
                dynamic toTest           = new DynamicStoredProcedure(ctx, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Asynchronous, true);
                IEnumerable <Person> res = await toTest.usp_GetPeople().ConfigureAwait(true);

                SynchronizationContext.SetSynchronizationContext(oldContext);

                res.Should()
                .ContainSingle("only one row should be returned")
                .Which.FirstName.Should().Be("Foo", "that is the FirstName of the item returned");
                count.Should().Be(1, "the callback should be posted to the SynchronizationContext");
            }
예제 #5
0
            public void CanCastExplicitly()
            {
                var ctx = CreatePeople("Foo");

                dynamic toTest = new DynamicStoredProcedure(ctx, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Synchronous, true);

                var people = (IEnumerable <Person>)toTest.usp_GetPeople();

                Assert.AreEqual("Foo", people.Single().FirstName);
            }
예제 #6
0
            public void CanCallAsyncWithNoArguments()
            {
                var ctx = CreatePeople("Foo");

                var toTest = new DynamicStoredProcedure(ctx, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Asynchronous, true);

                var result = GetPeople(toTest).Result;

                result.Single().FirstName.Should().Be("Foo");
            }
예제 #7
0
            public void DisposesCommandWhen_Done_WithoutResults()
            {
                Mock <IDbCommand> cmd;
                var db = CreatePeople(out cmd, "Foo");

                var toTest = new DynamicStoredProcedure(db, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Asynchronous, true);

                Call(toTest, new { test = "bar" }).Wait();
                cmd.Verify(c => c.Dispose(), Times.Once());
            }
예제 #8
0
            public void CanCallWithoutArguments()
            {
                var ctx = CreatePeople("Foo");

                dynamic toTest = new DynamicStoredProcedure(ctx, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Synchronous, true);

                IEnumerable <Person> people = toTest.usp_GetPeople();

                people.Should().ContainSingle(p => p.FirstName == "Foo", "because that was the only person created");
            }
예제 #9
0
            public void CanGetSingleResultWithoutExpectingIEnumerable()
            {
                var ctx = CreatePeople("Foo");

                var toTest = new DynamicStoredProcedure(ctx, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Asynchronous, true);

                var foo = GetPerson(toTest).Result;

                foo.FirstName.Should().Be("Foo", "because that is the name of the only person returned by the Stored Procedure");
            }
예제 #10
0
            public void MultipleSchemasThrowsException()
            {
                var ctx = CreatePeople("Foo");

                dynamic toTest           = new DynamicStoredProcedure(ctx, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Synchronous, true);
                IEnumerable <string> res = null;
                Action shouldThrow       = () => res = toTest.foo.bar.usp_GetPeople();

                shouldThrow.ShouldThrow <StoredProcedureException>("because you can only specify one schema")
                .WithMessage("Schema already specified once. \n\tExisting schema: foo\n\tAdditional schema: bar");
            }
예제 #11
0
            public void CanGetMultipleResultSets()
            {
                var ctx = CreateFamily();

                dynamic toTest = new DynamicStoredProcedure(ctx.Object, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Synchronous, true);

                Tuple <IEnumerable <Person>, IEnumerable <Family> > results = toTest.usp_GetPeople();

                results.Item1.Single().FirstName.Should().Be("Foo", "First result set not returned.");
                results.Item2.Single().LastName.Should().Be("Bar", "Second result set not returned.");
            }
예제 #12
0
            public void DisposesCommandWhen_Done_WithSingleResult()
            {
                Mock <IDbCommand> cmd;
                var db = CreatePeople(out cmd, "Foo");

                var toTest = new DynamicStoredProcedure(db, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Asynchronous, true);

                var foo = GetPerson(toTest).Result;

                cmd.Verify(c => c.Dispose(), Times.Once());
            }
예제 #13
0
            public void CastingToWrongItemTypeThrows()
            {
                var ctx = CreatePeople("Foo");

                IEnumerable <int> results = null;
                dynamic           toTest  = new DynamicStoredProcedure(ctx, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Synchronous, true);

                this.Invoking(_ => results = (IEnumerable <int>)toTest.usp_GetPeople())
                .ShouldThrow <StoredProcedureColumnException>("casting a result set to the wrong item type should fail");
                results.Should().BeNull("casting a result set to the wrong item type should fail");
            }
예제 #14
0
            public void DisposesCommandWhenDone_WithResults()
            {
                Mock <IDbCommand> cmd;
                var db = CreatePeople(out cmd, "Foo");

                dynamic toTest = new DynamicStoredProcedure(db, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Synchronous, true);

                IEnumerable <Person> people = toTest.usp_GetPeople();

                cmd.Verify(c => c.Dispose(), Times.Once());
            }
예제 #15
0
            public void DisposesCommandWhen_Done_WithMultipleResults()
            {
                Mock <IDbCommand> cmd;
                var db = CreateFamily(out cmd);

                var toTest = new DynamicStoredProcedure(db.Object, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Asynchronous, true);

                var result = GetPerson(toTest).Result;

                cmd.Verify(c => c.Dispose(), Times.Once());
            }
예제 #16
0
            public void ConfigureAwaitControlsThreadContinuationHappensOn()
            {
                // sleep so the task won't get inlined
                var ctx = CreatePeople(_ => Thread.Sleep(250), "Foo");

                var toTest = new DynamicStoredProcedure(ctx, transformers, CancellationToken.None, 400, DynamicExecutionMode.Asynchronous, true);

                var res = GetPeopleInBackground(toTest).Result;

                res.Should()
                .ContainSingle("only one row should be returned")
                .Which.FirstName.Should().Be("Foo", "that is the FirstName of the item returned");
            }
예제 #17
0
            public async Task CanCastExplicitly()
#endif
            {
                var ctx = CreatePeople("Foo");

                dynamic toTest = new DynamicStoredProcedure(ctx, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Asynchronous, true);

                var people = await(Task <IEnumerable <Person> >) toTest.usp_GetPeople();

                people.Should()
                .ContainSingle("only one row should be returned")
                .Which.FirstName.Should().Be("Foo", "that is the FirstName of the item returned");
            }
예제 #18
0
            public void CanPassDBNullParameter()
            {
                var ctx = CreatePeople(parms =>
                {
                    var parm = ((IDbDataParameter)parms[0]);
                    parm.ParameterName.Should().Be("id", "it is the name passed in the stored procedure");
                    parm.Direction.Should().Be(ParameterDirection.Input, "because the parameter is an input parameter");
                    parm.Value.Should().Be(DBNull.Value, "because DBNull was passed");
                });

                dynamic toTest = new DynamicStoredProcedure(ctx, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Synchronous, true);

                toTest.usp_GetPeople(id: DBNull.Value);
            }
예제 #19
0
            public void ClosesClonedConnectionWhenDone_WithMultipleResults()
            {
                var db  = new Mock <IDbConnection>();
                var db2 = CreateFamily();

                db.As <ICloneable>().Setup(d => d.Clone()).Returns(db2.Object);

                var toTest = new DynamicStoredProcedure(db.Object, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Asynchronous, true);

                var result = GetFamilies(toTest).Result;

                db2.Verify(d => d.Close(), Times.Once());
                db.Verify(d => d.Close(), Times.Never());
            }
예제 #20
0
            public void ClosesClonedConnectionWhenDone_WithoutResults()
            {
                var db  = new Mock <IDbConnection>();
                var db2 = CreatePeople("Foo");

                db.As <ICloneable>().Setup(d => d.Clone()).Returns(db2);

                var toTest = new DynamicStoredProcedure(db.Object, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Asynchronous, true);

                Call(toTest, new { test = "bar" }).Wait();

                Mock.Get(db2).Verify(d => d.Close(), Times.Once());
                db.Verify(d => d.Close(), Times.Never());
            }
예제 #21
0
            public void UnnamedParameters_Throw_Useful_Exception()
            {
                var     ctx    = CreatePeople("Foo");
                dynamic toTest = new DynamicStoredProcedure(ctx, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Synchronous, true);

                try
                {
                    toTest.usp_GetPeople("foo");
                }
                catch (StoredProcedureException ex)
                {
                    ex.Message.Should().Be(DynamicStoredProcedure.namedParameterException);
                }
            }
예제 #22
0
            public void ClosesClonedConnectionWhenDone_WithResults()
            {
                var db  = new Mock <IDbConnection>();
                var db2 = CreatePeople("Foo");

                db.As <ICloneable>().Setup(d => d.Clone()).Returns(db2);

                dynamic toTest = new DynamicStoredProcedure(db.Object, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Synchronous, true);

                IEnumerable <Person> people = toTest.usp_GetPeople();

                Mock.Get(db2).Verify(d => d.Close(), Times.Once());
                db.Verify(d => d.Close(), Times.Never());
            }
예제 #23
0
            public void CanSpecifyCustomSchema()
            {
                var ctx = CreatePeople("Foo");

                dynamic toTest = new DynamicStoredProcedure(ctx, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Synchronous, true);

                IEnumerable <string> people = toTest.foo.usp_GetPeople();

                people.Should().ContainSingle("Foo", "because only one person should have been returned.");

                // our setup will only ever return this one object
                var cmd = ctx.CreateCommand();

                cmd.CommandText.Should().Be("[foo].[usp_GetPeople]", "because we called the stored procedure with another schema.");
            }
예제 #24
0
            public void CanCallWithOutParameterNoQuery()
            {
                var ctx = CreatePeople(parms =>
                {
                    var parm = ((IDbDataParameter)parms[0]);
                    Assert.AreEqual(ParameterDirection.Output, parm.Direction, "Not passed as Output");
                    parm.Value = 42;
                });

                dynamic toTest = new DynamicStoredProcedure(ctx, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Synchronous, true);

                int id;

                toTest.usp_StoredProc(id: out id);

                Assert.AreEqual(42, id, "Out parameter not set.");
            }
예제 #25
0
            public void CanExecuteAsyncWithOutParameterValue()
            {
                var ctx = CreatePeople(parms =>
                {
                    var parm = ((IDbDataParameter)parms[0]);
                    Assert.AreEqual(ParameterDirection.Output, parm.Direction, "Not passed as Output");
                    parm.Value = 42;
                }, "Bar", "Baz");

                var toTest = new DynamicStoredProcedure(ctx, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Asynchronous, true);

                var output = new Output();
                var people = GetPeople(toTest, output).Result;

                Assert.AreEqual(42, output.Value, "Out parameter not set.");
                Assert.IsTrue(people.Select(p => p.FirstName).SequenceEqual(new[] { "Bar", "Baz" }));
            }
예제 #26
0
            public void CanExecuteAsyncWithReturnValue()
            {
                var ctx = CreatePeople(parms =>
                {
                    var parm = ((IDbDataParameter)parms[0]);
                    Assert.AreEqual(ParameterDirection.ReturnValue, parm.Direction, "Not passed as ReturnValue");
                    parm.Value = 42;
                }, "Foo", "Bar");

                var toTest = new DynamicStoredProcedure(ctx, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Asynchronous, true);

                var retValue = new Return();
                var people   = GetPeople(toTest, retValue).Result;

                Assert.AreEqual(42, retValue.Value, "Return value not set.");
                Assert.IsTrue(people.Select(p => p.FirstName).SequenceEqual(new[] { "Foo", "Bar" }));
            }
예제 #27
0
            public void CanCallAsyncWithOutParameterNonQuery()
            {
                var ctx = CreateNonQuery(parms =>
                {
                    var parm = ((IDbDataParameter)parms[0]);
                    Assert.AreEqual(ParameterDirection.Output, parm.Direction, "Not passed as Output");
                    parm.Value = 42;
                });

                var toTest = new DynamicStoredProcedure(ctx, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Asynchronous, false);

                var output = new Output();

                Call(toTest, output).Wait();

                Assert.AreEqual(42, output.Value, "Out parameter not set.");
            }
예제 #28
0
            public void CanCallAsyncWithReturnValueFromNonQuery()
            {
                var ctx = CreateNonQuery(parms =>
                {
                    var parm = ((IDbDataParameter)parms[0]);
                    Assert.AreEqual(ParameterDirection.ReturnValue, parm.Direction, "Not passed as ReturnValue");
                    parm.Value = 42;
                });

                var toTest = new DynamicStoredProcedure(ctx, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Asynchronous, false);

                var retValue = new Return();

                Call(toTest, retValue).Wait();

                Assert.AreEqual(42, retValue.Value, "Return value not set.");
            }
예제 #29
0
            public void ClosesClonedConnectionWhenDone_WithResults()
            {
                var db  = new Mock <IDbConnection>();
                var db2 = CreatePeople(_ => { }, "Foo");

                db.As <ICloneable>().Setup(d => d.Clone()).Returns(() => db2);

                var toTest = new DynamicStoredProcedure(db.Object, transformers, CancellationToken.None, TEST_TIMEOUT, DynamicExecutionMode.Asynchronous, true);

                var result = GetPeople(toTest).Result;

                db.Verify(d => d.Open(), Times.Never());
                db.Verify(d => d.CreateCommand(), Times.Never());
                db.As <ICloneable>().Verify(d => d.Clone(), Times.Once());
                Mock.Get(db2).Verify(d => d.Open(), Times.Once());
                Mock.Get(db2).Verify(d => d.CreateCommand(), Times.Once());
                Mock.Get(db2).Verify(d => d.Close(), Times.Once());
                db.Verify(d => d.Close(), Times.Never());
            }
예제 #30
0
            public void CancelledTokenWillNotExecute()
            {
                var ctx = CreatePeople(_ =>
                {
                    throw new Exception("Should have been cancelled.");
                });
                var cts = new CancellationTokenSource();

                cts.Cancel();

                this.Invoking(_ =>
                {
                    dynamic toTest = new DynamicStoredProcedure(ctx, transformers, cts.Token, TEST_TIMEOUT, DynamicExecutionMode.Synchronous, true);

                    var value = 13;
                    IEnumerable <Person> people = toTest.usp_StoredProc(value: value);
                    people.Should().BeEmpty("The execution was cancelled.");
                }).ShouldThrow <OperationCanceledException>("because the execution has already been cancelled.");
            }