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