- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
请考虑以下代码:
public class TestingSample
{
public class FactoryClass : Class {}
public class Class : IInterface {}
public interface IInterface {}
public class AutoData : AutoDataAttribute
{
public AutoData() : base( Create() ) {}
static IFixture Create()
{
var fixture = new Fixture();
fixture.Customize<IInterface>( composer => composer.FromFactory( () => new FactoryClass() ) );
fixture.Customize<Class>( composer => composer.FromFactory( () => new FactoryClass() ) );
return fixture;
}
}
[Theory, TestingSample.AutoData]
public void OldSkool( [Frozen( As = typeof(IInterface) )]Class first, Class second, IInterface third )
{
Assert.IsType<FactoryClass>( first );
Assert.Same( first, second );
Assert.Same( first, third );
}
[Theory, TestingSample.AutoData]
public void DirectBaseType( [Frozen( Matching.ExactType )]Class first, Class second )
{
Assert.IsType<FactoryClass>( first );
Assert.Same( first, second );
}
[Theory, TestingSample.AutoData]
public void ImplementedInterfaces( [Frozen( Matching.ImplementedInterfaces )]Class first, IInterface second )
{
Assert.IsType<FactoryClass>( first );
Assert.Same( first, second ); // The Fails.
}
}
正如您(希望)看到的,ImplementedInterfaces
测试失败。由于 FrozenAttribute.As 已被弃用,并且用户已被引导到 Match 枚举,我的期望是它的行为与以前相同。
但是,Match.ImplementedInterfaces
的行为似乎与 Match.ExactType
和 FrozenAttribute.As
不同。
我确实做了一些探索,发现 Match.ExactType
和 FrozenAttribute.As
使用了 SeedRequestSpecification
而 Match. ImplementedInterfaces
仅匹配 Type
请求。
是否有可能获得有关此行为的一些背景信息?这是设计使然吗?如果是这样,是否有已知的建议来设计,以使用 Match.ImplementedInterfaces
恢复旧行为?
最佳答案
首先,附带条件:在我的机器上,使用 AutoFixture 3.39.0,OP 中提供的代码的行为完全与描述不符。不同之处在于,此测试中的第一个断言通过了:
[Theory, TestingSample.AutoData]
public void ImplementedInterfaces(
[Frozen(Matching.ImplementedInterfaces)]Class first,
IInterface second)
{
Assert.IsType<FactoryClass>(first); // passes
Assert.Same(first, second); // fails
}
不过,我承认第二个断言失败是(有点)令人惊讶的。
简单的解释是,在当前的实现中,卡住是在反射时完成的,而不是在运行时完成的。当 AutoFixture.Xunit2 确定要卡住的内容时,它会查看应用了 [Frozen] 属性的参数类型。这是 Class
,而不是 FactoryClass
,因此结果是 FactoryClass
根本没有卡住!
您可以从这个测试中看到这一点:
[Theory, TestingSample.AutoData]
public void FactoryClassIsNotFrozen(
[Frozen(Matching.ImplementedInterfaces)]Class first,
FactoryClass second)
{
Assert.IsType<FactoryClass>(first); // passes
Assert.IsType<FactoryClass>(second); // passes
Assert.Same(first, second); // fails
}
这是最好的实现吗?也许不是,但这就是目前的运作方式。有an open issue in the AutoFixture GitHub repository建议应该重构 freeze 实现,使其更像 DI 容器的 Singleton 生命周期。这可能会将这种特定场景中的行为改变为更适合它的行为。它是否也会有一些缺点,目前我还无法判断。
当我们重新设计[Frozen]
属性以使用更灵活的Matching
规则时,我意识到新系统无法100%替换旧的 As
属性。我仍然认为这种权衡是值得的。
虽然 As
使您能够让此特定功能发挥作用,但这是因为您作为程序员知道 Class
实现了 IInterface
,因此 [Frozen(As = typeof(IInterface))]
注释是有意义的。
您可能会说 As
更灵活,但这主要是因为它没有内置智能。您也可以编写 [Frozen(As = typeof(IAsyncResult))]
并且可以很好地编译 - 只是在运行时失败,因为它完全是无意义的。
is there a known recommendation to design in such a way to restore the old behavior using Match.ImplementedInterfaces?
是的,考虑简化被测系统 (SUT) 的设计。
AutoFixture 最初被设想为测试驱动开发工具,这仍然是其主要目的。本着GOOS的精神,我们应该听测试。如果测试很难编写,第一 react 应该是简化 SUT。 AutoFixture 往往会放大来自测试的此类反馈。
您真的需要匹配既实现接口(interface)又派生自基类的东西吗?为什么?
能不能再简单一点?
关于c# - 为什么 Matching.ImplementedInterfaces 的行为与 Matching.ExactType 和 FrozenAttribute.As 不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34840015/
请考虑以下代码: public class TestingSample { public class FactoryClass : Class {} public class Clas
我是一名优秀的程序员,十分优秀!