I've recently started using AutoFixture+AutoMoq and I'm trying to create an instance of Func<IDbConnection>
(i.e., a connection factory).
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var connectionFactory = fixture.Create<Func<IDbConnection>>();
This seems to work rather well:
- My system under test can call the delegate and it will get a mock of
IDbConnection
- On which I can then call
CreateCommand
, which will get me a mock ofIDbCommand
- On which I can then call
ExecuteReader
, which will get me a mock ofIDataReader
I now want to perform additional setups on the mock of IDataReader
, such as make it return true
when Read()
is called.
From what I've read, I should be using Freeze
for this:
var dataReaderMock = fixture.Freeze<Mock<IDataReader>>();
dataReaderMock.Setup(dr => dr.Read())
.Returns(true);
This doesn't seem to meet my expectations though. When I call IDbCommand.ExecuteReader
, I'll get a different reader than the one I just froze/setup.
Here's an example:
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var dataReaderMock = fixture.Freeze<Mock<IDataReader>>();
dataReaderMock.Setup(dr => dr.Read())
.Returns(true);
//true - Create<IDataReader> retrieves the data reader I just mocked
Assert.AreSame(dataReaderMock.Object, fixture.Create<IDataReader>());
//false - IDbCommand returns a different instance of IDataReader
Assert.AreSame(dataReaderMock.Object, fixture.Create<IDbCommand>().ExecuteReader());
What am I doing wrong? How do I get other fixtures, such as IDbCommand
, to use the mocked instance of IDataReader
?
MockConfigurator
source, I can see the mock's default value is being set toDefaultValue.Mock
, and that's whyExecuteReader
gets be a brand new mock ofIDataReader
. I'll see if I can create my own configurator to setup every method to make the mock call back into thefixture
and get its return instance from the container. – Eighth