FakeItEasy框架中设置Fake对象属性值不生效问题咨询
解决FakeItEasy中设置MapLevel.Bounds属性不生效的问题
我懂你遇到的困扰了——明明手动给假对象mapLevel的Bounds属性赋了值,后续访问时却拿到的是FakeItEasy生成的默认假值,完全不是你设置的Rectangle(0, 0, 100, 100)。这是因为你对FakeItEasy处理类假对象属性的逻辑理解有偏差,咱们一步步来修正:
问题根源
当你用A.Fake<MapLevel>()创建类的假对象时,FakeItEasy默认只会拦截并处理虚拟(virtual)成员。如果MapLevel的Bounds属性不是虚拟的,直接赋值的操作不会被FakeItEasy记录,后续访问属性时,框架会返回它默认生成的假对象;就算Bounds是虚拟属性,直接赋值也不是FakeItEasy推荐的配置方式,框架的拦截逻辑会覆盖你的手动赋值。
修正方案
你需要用FakeItEasy的专属API来配置属性的返回值,而非直接赋值。修改后的代码如下:
var gameWorld = A.Fake<IGameWorld>(); var entityManager = A.Fake<IEntityManager>(); A.CallTo(() => gameWorld.EntityManager).Returns(entityManager); var mapLevel = A.Fake<MapLevel>(); A.CallTo(() => entityManager.GetCurrentAirSeaMapLevel()).Returns(mapLevel); var bounds = new Rectangle(0, 0, 100, 100); // 替换直接赋值,用FakeItEasy的API配置属性返回值 A.CallTo(() => mapLevel.Bounds).Returns(bounds);
如果Bounds属性有公开的setter,你也可以用CallToSet语法来配置:
A.CallToSet(() => mapLevel.Bounds).To(bounds);
额外提醒:如果MapLevel的Bounds属性不是虚拟的,上面的配置会失效。这时候你需要把Bounds改成虚拟属性,或者让MapLevel实现一个包含Bounds属性的接口,转而伪造这个接口。
内容的提问来源于stack exchange,提问作者Marco




