gpt4 book ai didi

c# - Moq 上的扩展方法返回 null

转载 作者:太空狗 更新时间:2023-10-30 01:13:32 24 4
gpt4 key购买 nike

我尝试测试使用扩展方法调用的某些函数的结果。此扩展方法是在接口(interface)上定义的。测试设置创建了所述接口(interface)的模拟。对于这个模拟,配置了两个设置。在模拟接口(interface)实现上调用这些设置函数时,一切都按预期进行。 (参见 TestMockSetupSourceClassA 和 TestMockSetupSourceClassB)但是当在扩展方法中进行这些调用时,结果为空。 (参见 TestDoClassStuff)

我设置了一个测试项目:https://github.com/sschauss/MoqExtensionMethodTest

扩展

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));
}
}

实现

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);
}
}

测试

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);
}
}

最佳答案

问题与 Aggregate 扩展、它的通用参数参数以及您对模拟所期望的 Setup 有关。

扩展方法 DoExtensionStuffparams 是一个 object 数组,所以在调用 `

T2 DoInterfaceStuff<T1, T2>(T1 parameter1, T2 parameter2)

在您实际传递的 Aggregate 委托(delegate)中

 (TResult agg, object cur) => someInterface.DoInterfaceStuff<object,TResult>(cur, agg)

模拟未配置为处理。

在更改 _someInterfaceMock.Setup 之后,在这种特殊情况下,明确地更改为

 _someInterfaceMock
.Setup(m => m.DoInterfaceStuff<object, TargetClass>(_sourceB, _target))
.Returns(_target);

此场景中的所有测试都能够成功完成。

Moq 的问题在于,如果没有明确地告诉 mock 期望什么,它将默认为引用类型返回 null

关于c# - Moq 上的扩展方法返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49792395/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com