Extension Method on Moq returns null
我尝试测试一些调用扩展方法的函数的结果。这个扩展方法是在一个接口上定义的。测试设置创建了所述接口的模拟。对于这个模拟,配置了两个设置。在模拟接口实现上调用这些设置函数时,一切都按预期工作。 (请参阅 TestMockSetupSourceClassA 和 TestMockSetupSourceClassB)但是当在扩展方法中进行这些调用时,结果为空。 (参见 TestDoClassStuff)
我已经建立了一个测试项目:https://github.com/sschauss/MoqExtensionMethodTest
扩展
1 2 3 4 5 6 7 8 9 | public static class ExtensionClass { public static TResult DoExtensionStuff<TResult>(this ISomeInterface someInterface, object initialObject, params object[] objects) { var result = someInterface.DoInterfaceStuff<TResult>(initialObject); return objects.Aggregate(result, (agg, cur) => someInterface.DoInterfaceStuff(cur, agg)); } } |
实施
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public class SomeClass { private readonly ISomeInterface _someInterface; public SomeClass(ISomeInterface someInterface) { _someInterface = someInterface; } public TargetClass DoClassStuff(SourceClassA sourceClassA, SourceClassB sourceClassB) { return _someInterface.DoExtensionStuff<TargetClass>(sourceClassA, sourceClassB); } } |
测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | public class UnitTest { private readonly SomeClass _sut; private readonly SourceClassA _sourceA; private readonly SourceClassB _sourceB; private readonly TargetClass _target; private readonly Mock<ISomeInterface> _someInterfaceMock; public UnitTest() { _sourceA = new SourceClassA { Integer = 1 }; _sourceB = new SourceClassB { String ="stringB" }; _target = new TargetClass { Integer = 2, String ="stringT" }; _someInterfaceMock = new Mock<ISomeInterface>(); _someInterfaceMock.Setup(m => m.DoInterfaceStuff<TargetClass>(_sourceA)).Returns(_target); _someInterfaceMock.Setup(m => m.DoInterfaceStuff(_sourceB, _target)).Returns(_target); _sut = new SomeClass(_someInterfaceMock.Object); } [Fact] public void TestDoClassStuff() { var result = _sut.DoClassStuff(_sourceA, _sourceB); result.Should().BeEquivalentTo(_target); } [Fact] public void TestMockSetupSourceClassA() { var result = _someInterfaceMock.Object.DoInterfaceStuff<TargetClass>(_sourceA); result.Should().BeEquivalentTo(_target); } [Fact] public void TestMockSetupSourceClassB() { var result = _someInterfaceMock.Object.DoInterfaceStuff(_sourceB, _target); result.Should().BeEquivalentTo(_target); } } |
问题与
扩展方法
1 | T2 DoInterfaceStuff<T1, T2>(T1 parameter1, T2 parameter2) |
在
1 | (TResult agg, object cur) => someInterface.DoInterfaceStuff<object,TResult>(cur, agg) |
模拟未配置为处理的。
在更改
1 2 3 | _someInterfaceMock .Setup(m => m.DoInterfaceStuff<object, TargetClass>(_sourceB, _target)) .Returns(_target); |
此场景中的所有测试都能够成功完成。
Moq 的问题是,当一个 mock 没有被明确告知期望什么时,默认情况下它会为引用类型返回 null。