使用AutoFixture模拟依赖项

dca*_*tro 5 c# unit-testing moq autofixture automoq

我最近开始使用AutoFixture + AutoMoq,我正在尝试创建一个实例Func<IDbConnection>(即连接工厂).

var fixture = new Fixture().Customize(new AutoMoqCustomization());
var connectionFactory = fixture.Create<Func<IDbConnection>>();
Run Code Online (Sandbox Code Playgroud)

这看起来效果很好:

  1. 我的测试系统可以调用代理,它将得到一个模拟 IDbConnection
  2. 然后我可以打电话CreateCommand,这将让我嘲笑IDbCommand
  3. 然后我可以打电话ExecuteReader,这将让我嘲笑IDataReader

我现在想在模拟上执行其他设置IDataReader,例如让它trueRead()调用时返回.

从我所读到的,我应该Freeze用于此:

var dataReaderMock = fixture.Freeze<Mock<IDataReader>>();

dataReaderMock.Setup(dr => dr.Read())
                      .Returns(true);
Run Code Online (Sandbox Code Playgroud)

这似乎不符合我的期望.当我打电话时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());
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?我如何获得其他装置,例如IDbCommand,使用模拟的实例IDataReader

dca*_*tro 5

截至3.20.0,您可以使用AutoConfiguredMoqCustomization.这将自动配置所有模拟,以便其成员的返回值由AutoFixture生成.

例如,IDbConnetion.CreateCommand将自动配置为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());
Run Code Online (Sandbox Code Playgroud)

  • `AutoConfiguredMoqCustomization` 现在已过时,首选 `AutoMoqCustomization`。 (2认同)