AutoFixture 构建-冻结-创建序列
AutoFixture Build-Freeze-Create sequence
我刚刚注意到,每当我在 Build<>()
-Create()
调用之间的夹具上执行 Freeze
时,Freeze
不会被应用。这是 AutoFixture 的预期行为还是错误?
要说清楚:
var fixture = new Fixture().Customize(new AutoMoqCustomization())
var builder = fixture.Build<SomeType>();
fixture.Freeze<Mock<ISomeInterface>>().Setup(m => m.SomeProperty).Returns(10);
var sut = builder.Create();
// if SomeType uses ISomeInterface.SomeProperty it will get 0 returned - *incorrect*
这很好用:
var fixture = new Fixture().Customize(new AutoMoqCustomization())
fixture.Freeze<Mock<ISomeInterface>>().Setup(m => m.SomeProperty).Returns(10);
var sut = fixture.Create<SomeType>();
// if SomeType uses ISomeInterface.SomeProperty it will get 10 returned - correct
如果您在调用生成器之前冻结,它将起作用
冻结-构建-创建序列
[TestClass]
public class AutoFixtureTests {
[TestMethod]
public void _FreezeBuildCreate() {
//Arrange
var expected = 10;
var fixture = new Fixture().Customize(new AutoMoqCustomization());
fixture.Freeze<Mock<ISomeInterface>>().Setup(m => m.SomeProperty).Returns(expected);
var builder = fixture.Build<SomeType>();
var sut = builder.Create();
//Act
var actual = sut.GetA();
//Assert
Assert.AreEqual(expected, actual);
}
public class SomeType {
private ISomeInterface a;
public SomeType(ISomeInterface a) {
this.a = a;
}
public int GetA() {
return a.SomeProperty;
}
}
public interface ISomeInterface {
int SomeProperty { get; set; }
}
}
如果你看一下Build
方法的定义
Customizes the creation algorithm for a single object, effectively
turning off all Customizations on the Ploeh.AutoFixture.IFixture.
如果在冻结之前调用构建,则之后的所有自定义都不会生效。
这就是我自己解决这个问题的方法。由于我在选择放置 Build
-Create
的位置时没有太多选择,因此不得不为此使用事件。哦,我不想让 Create
虚拟化。
这是一些伪代码:
public class BaseSutBuilder<TSut> {
// other weird stuff...
// somewhere in ctor:
protected BaseSutBuilder() {
SutBuilders = _ => {};
}
protected Action<ICustomizationComposer<TSut>> SutBuilders { get; }
public TSut Create() {
var builder = _fixture.Build<TSut>();
SutBuilders(builder);
return builder.Create();
}
}
public class SomeTypeSutBuilder: BaseSutBuilder<SomeType> {
public SomeTypeSutBuilder() {
SutBuilders += c => c.With(.......
SutBuilders += c => c.With(.......
}
}
我刚刚注意到,每当我在 Build<>()
-Create()
调用之间的夹具上执行 Freeze
时,Freeze
不会被应用。这是 AutoFixture 的预期行为还是错误?
要说清楚:
var fixture = new Fixture().Customize(new AutoMoqCustomization())
var builder = fixture.Build<SomeType>();
fixture.Freeze<Mock<ISomeInterface>>().Setup(m => m.SomeProperty).Returns(10);
var sut = builder.Create();
// if SomeType uses ISomeInterface.SomeProperty it will get 0 returned - *incorrect*
这很好用:
var fixture = new Fixture().Customize(new AutoMoqCustomization())
fixture.Freeze<Mock<ISomeInterface>>().Setup(m => m.SomeProperty).Returns(10);
var sut = fixture.Create<SomeType>();
// if SomeType uses ISomeInterface.SomeProperty it will get 10 returned - correct
如果您在调用生成器之前冻结,它将起作用
冻结-构建-创建序列
[TestClass]
public class AutoFixtureTests {
[TestMethod]
public void _FreezeBuildCreate() {
//Arrange
var expected = 10;
var fixture = new Fixture().Customize(new AutoMoqCustomization());
fixture.Freeze<Mock<ISomeInterface>>().Setup(m => m.SomeProperty).Returns(expected);
var builder = fixture.Build<SomeType>();
var sut = builder.Create();
//Act
var actual = sut.GetA();
//Assert
Assert.AreEqual(expected, actual);
}
public class SomeType {
private ISomeInterface a;
public SomeType(ISomeInterface a) {
this.a = a;
}
public int GetA() {
return a.SomeProperty;
}
}
public interface ISomeInterface {
int SomeProperty { get; set; }
}
}
如果你看一下Build
方法的定义
Customizes the creation algorithm for a single object, effectively turning off all Customizations on the Ploeh.AutoFixture.IFixture.
如果在冻结之前调用构建,则之后的所有自定义都不会生效。
这就是我自己解决这个问题的方法。由于我在选择放置 Build
-Create
的位置时没有太多选择,因此不得不为此使用事件。哦,我不想让 Create
虚拟化。
这是一些伪代码:
public class BaseSutBuilder<TSut> {
// other weird stuff...
// somewhere in ctor:
protected BaseSutBuilder() {
SutBuilders = _ => {};
}
protected Action<ICustomizationComposer<TSut>> SutBuilders { get; }
public TSut Create() {
var builder = _fixture.Build<TSut>();
SutBuilders(builder);
return builder.Create();
}
}
public class SomeTypeSutBuilder: BaseSutBuilder<SomeType> {
public SomeTypeSutBuilder() {
SutBuilders += c => c.With(.......
SutBuilders += c => c.With(.......
}
}