[Moq] Mocking DbDataProvider

853 views
Skip to first unread message

Nuno Leong

unread,
May 21, 2010, 12:18:40 PM5/21/10
to Moq Discussions
Hi,

I'm relatively new to mocking frameworks so bear with me. :)

We're testing a couple of classes which depend on IDb* objects (sort
of a DAL). I was trying to mock DbFactoryProvider so we can inject
mock IDb objects to the classes.

So, i did this:

Mock<IDbCommand> mockIDbCommand = new
Mock<IDbCommand>(MockBehavior.Strict);
mockIDbCommand.SetupAllProperties();

Mock<IDbConnection> mockIDbConnection = new
Mock<IDbConnection>(MockBehavior.Strict);
mockIDbConnection.SetupAllProperties();
mockIDbConnection.Setup(c =>
c.CreateCommand()).Returns(mockIDbCommand.Object);

Mock<DbProviderFactory> mockDbProviderFactory = new
Mock<DbProviderFactory>(MockBehavior.Strict);
mockDbProviderFactory.Setup(f =>
f.CreateConnection()).Returns(mockIDbConnection.Object);

The last line won't compile since DbProviderFactory.CreateConnection()
returns an DbConnection and not an IDbConnection.

The problem is can't mock DbConnection.CreateCommand() since that
method is not virtual/overridable.

I tried casting mockIDbConnection.Object to DbConnection but that
doesn't work.

Any suggestions on how to solve this problem ?

Huge thanks,
Nuno Leong

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

Daniel Cazzulino

unread,
May 21, 2010, 12:44:55 PM5/21/10
to moq...@googlegroups.com
when an (typically legacy) API is not amenable to mocking, you can wrap it in a new interface and use that throughout your codebase.

An example of how to do this can be found at http://weblogs.asp.net/cibrax/archive/2008/05/16/unit-tests-for-wcf.aspx, where Pablo does esencially the same thing for the unmock-able WCF service context.

HTH

/kzu

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

Nuno Leong

unread,
May 21, 2010, 2:27:59 PM5/21/10
to Moq Discussions
Hi Daniel,

It worked perfectly, thanks a lot.

Cheers,
Nuno Leong

On May 21, 5:44 pm, Daniel Cazzulino <dan...@cazzulino.com> wrote:
> when an (typically legacy) API is not amenable to mocking, you can wrap it
> in a new interface and use that throughout your codebase.
>
> An example of how to do this can be found athttp://weblogs.asp.net/cibrax/archive/2008/05/16/unit-tests-for-wcf.aspx,

e...@baskoro.org

unread,
Jun 19, 2013, 11:19:53 PM6/19/13
to moq...@googlegroups.com
G'day,

Alternatively if you are targeting .NET 4.5 and using Moq 4 the following snippet works without creating wrappers:

// Mock the data reader
var dataReaderMock = new Mock<DbDataReader>();
dataReaderMock
    .Setup(dataReader => dataReader.HasRows)
    .Returns(true)
;
dataReaderMock.As<IDisposable>();

// Mock the command
var commandMock = new Mock<DbCommand>();
commandMock
    .Protected()
    .Setup<DbDataReader>("ExecuteDbDataReader", new object[] { CommandBehavior.Default })
    .Returns(dataReaderMock.Object)
;
commandMock.As<IDisposable>();

// Mock the connection
var connectionMock = new Mock<DbConnection>();
connectionMock
    .Protected()
    .Setup<DbCommand>("CreateDbCommand")
    .Returns(commandMock.Object)
;
connectionMock.As<IDisposable>();

// Mock the provider factory
var providerFactoryMock = new Mock<DbProviderFactory>();
providerFactoryMock
    .Setup(providerFactory => providerFactory.CreateConnection())
    .Returns(connectionMock.Object)
;

Warm regards,

Eki Baskoro B.Com. B.Eng. SCJP MCTS MCP
Reply all
Reply to author
Forward
0 new messages