我最近开始使用 AutoFixture+AutoMoq,我正在尝试创建 Func<IDbConnection>
的实例(即连接工厂)。
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var connectionFactory = fixture.Create<Func<IDbConnection>>();
这似乎工作得很好:
- 我的测试系统可以调用委托(delegate),它会得到
IDbConnection
的模拟。 - 然后我可以在上面调用
CreateCommand
, 这会让我模拟IDbCommand
- 然后我可以在上面调用
ExecuteReader
, 这会让我模拟IDataReader
我现在想在 IDataReader
的模拟上执行额外的设置, 比如让它返回 true
什么时候Read()
被称为。
根据我的阅读,我应该使用 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
的模拟实例?
最佳答案
从 3.20.0 开始,您可以使用 AutoConfiguredMoqCustomization
。这将自动配置所有模拟,以便其成员的返回值由 AutoFixture 生成。
例如,IDbConnetion.CreateCommand
将被自动配置为从 fixture 返回一个 IDbCommand
,而 IDbCommand.ExecuteReader
将被自动配置为从夹具返回一个 IDataReader
。
所有这些测试现在应该通过了:
var fixture = new Fixture().Customize(new AutoConfiguredMoqCustomization());
var dataReaderMock = fixture.Freeze<Mock<IDataReader>>();
dataReaderMock.Setup(dr => dr.Read())
.Returns(true);
//all pass
Assert.Same(dataReaderMock.Object, fixture.Create<IDataReader>());
Assert.Same(dataReaderMock.Object, fixture.Create<IDbCommand>().ExecuteReader());
Assert.Same(dataReaderMock.Object, fixture.Create<IDbConnection>().CreateCommand().ExecuteReader());
Assert.Same(dataReaderMock.Object, fixture.Create<Func<IDbConnection>>()().CreateCommand().ExecuteReader());
关于c# - 使用 AutoFixture 模拟依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25055661/