我最近开始使用AutoFixture+AutoMoq,尝试创建一个Func<IDbConnection>
实例(即连接工厂)。
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var connectionFactory = fixture.Create<Func<IDbConnection>>();
这似乎相当有效:
1. 我的测试系统可以调用委托,并获得
IDbConnection
的模拟对象。
2. 然后我可以调用CreateCommand
,它将为我提供IDbCommand
的模拟对象。
3. 然后我可以调用ExecuteReader
,它将为我提供IDataReader
的模拟对象。现在,我想对
IDataReader
的模拟对象执行其他设置,例如使其在调用Read()
时返回true
。根据我的阅读,我应该使用
Freeze
来实现这一点:var dataReaderMock = fixture.Freeze<Mock<IDataReader>>();
dataReaderMock.Setup(dr => dr.Read())
.Returns(true);
然而,这似乎并不符合我的期望。当我调用IDbCommand.ExecuteReader
时,得到的读取器与我之前冻结/设置的读取器不同。
以下是一个例子:
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());
我做错了什么?如何让其他装置,例如
IDbCommand
,使用模拟的IDataReader
实例?
MockConfigurator
源码,我发现mock的默认值被设置为DefaultValue.Mock
,这就是为什么ExecuteReader
会得到一个全新的IDataReader
mock。我会尝试创建自己的配置器来设置每个方法,使mock回调到fixture
并从容器中获取其返回实例。 - dcastro