IDbCommand.Parameters

660 views
Skip to first unread message

caloggins

unread,
Dec 31, 2009, 11:13:05 AM12/31/09
to Moq Discussions
I am somewhat new to Moq, and am having trouble a bit of trouble with
mocking IDdCommand. I wish to write a test for a class which
implements NHibernate's IUserType interface. I cannot figure out how
to create a mock of the Parameters property (it's read-only), so I can
test if a value is set. One attempt looks like the following:

[Test]
public void NullSafeSetWithMinDateTimeTest()
{
var test = new DateTime(2008, 01, 31);
var index = 0;

var paramsMock = new Mock<IDataParameterCollection>();
var valueMock = new Mock<IDataParameter>();
valueMock.Setup(o => o.Value);
paramsMock.Object.Add(valueMock.Object);

_mock.Setup(o => o.Parameters).Returns(paramsMock.Object);

var obj = new DateTimeUserType();
obj.NullSafeSet(_mock.Object, test, index);

Assert.That(((IDataParameter)paramsMock.Object
[index]).Value, Is.EqualTo("20080131"));
}

But, it throws an exception when the NullSafeSet method attempts to
set the value of the first index.

So, in short, how do I mock the Parameters property of the IDbCommand
interface?

Matt Hamilton

unread,
Jan 3, 2010, 4:43:07 PM1/3/10
to moq...@googlegroups.com
Here's a test I use which mocks the parameters on a command.

This is using the old "Expect/Verify" syntax, but maybe it will help.

Basically you need to set up a "Get" on the command so that your mocked
IDataParameterCollection is returned when the code asks for cmd.Parameters.
Once that's done, you can mock out the "CreateParameter" method on the
collection and verify that the mocked param's value was set as you expected.

Matt

var cmd = factory.Create<IDbCommand>();
var parms = factory.Create<IDataParameterCollection>();
var idParam = factory.Create<IDbDataParameter>();

cmd.ExpectSet(c => c.CommandText,
EntriesDbRepository.GetPigSexCommandText);
cmd.ExpectSet(c => c.CommandType, CommandType.Text);
cmd.ExpectSet(c => c.Transaction, txn);

cmd.Expect(c => c.CreateParameter()).Returns(idParam.Object);
cmd.ExpectGet(c => c.Parameters).Returns(parms.Object);
cmd.Expect(c => c.ExecuteScalar()).Returns(sex);
cmd.Expect(c => c.Dispose());

idParam.ExpectSet(p => p.ParameterName, "id");
idParam.ExpectSet(p => p.Value, id);

parms.Expect(p => p.Add(idParam.Object)).Returns(0);

return cmd;


--------------------------------------------------
From: "caloggins" <gsa...@gmail.com>
Sent: Friday, January 01, 2010 3:13 AM
To: "Moq Discussions" <moq...@googlegroups.com>
Subject: [Moq] IDbCommand.Parameters

> --
> Post: moq...@googlegroups.com
> Unsubscribe: moqdisc-u...@googlegroups.com
>
>

Daniel Cazzulino

unread,
Jan 3, 2010, 5:08:33 PM1/3/10
to moq...@googlegroups.com
what's wrong in this approach is that you're using the mocked collection as if it had an implementation, expecting that callling Add on it will actually do something. it will not, as it's an interface, and you have not set the mock in any way to do anything:

           paramsMock.Object.Add(valueMock.Object);

you should setup the collection to return what you want when the indexer is accessed instead, something like:

paramsMock.SetupGet(x => x[index]).Returns(valueMock.Object);


/kzu
--
Daniel Cazzulino | Developer Lead | XML MVP | Clarius Consulting | +1 425.329.3471


caloggins

unread,
Jan 5, 2010, 6:49:08 AM1/5/10
to Moq Discussions
Ah! Thank you both very much.

On Jan 3, 5:08 pm, Daniel Cazzulino <k...@clariusconsulting.net>
wrote:

Reply all
Reply to author
Forward
0 new messages