c# - Mock 上的设置未返回预期值

标签 c# unit-testing moq

这是我遇到的一个问题的简化版本:

public interface IService
{
    IProvider Provider { get; }
}

public interface IProvider
{
    List<int> Numbers{ get; }
    string Text { get; }
} 

[TestMethod]
public void ServiceTest()
{
    var service = new Mock<IService>();
    var provider = new Mock<IProvider>();

    service.Setup(s => s.Provider).Returns(provider.Object);    // A
    service.Setup(s => s.Provider.Text).Returns("some text");   // B - incorrect

    // they actually meant to do this, instead of 'B'
    // provider.Setup(p => p.Text).Returns("some text"); 

    provider.Setup(p => p.Numbers).Returns(new List<int> { 1, 2, 3 });

    DummyApplicationCode(service.Object);
}

int DummyApplicationCode(IService service)
{
    // will throw, because the Provider was replaced at 'B'
    int shouldBeOne = service.Provider.Numbers.First(); 
    return shouldBeOne;
}

单元测试失败,因为在被测应用程序代码中,模拟的 IService 返回了错误的 IProvider

我最终发现了导致它的行(请记住我正在查看的代码并不像上面那么简单),上面标记为“B”,这是其他人添加的误解最小起订量设置。

我知道模拟的后续设置会覆盖之前的设置,但我没有发现这个问题,因为有问题的行的返回是针对单独的子属性的。

我希望这是设计使然,但它让我震惊,因为我没想到有人会这样做。

我的问题:由于“B”处的设置仅与提供者Text 的返回有关,为什么服务“Provider”属性需要替换它这是在“A”处定义的?

最佳答案

从源代码来看,这显然是故意的:

https://github.com/moq/moq4/blob/master/Source/Mock.cs

https://github.com/moq/moq4/blob/master/Source/Interceptor.cs

Setup 通过在 Interceptor 上使用 AddCall 创建一个“调用”。这包含以下代码块,只要我们创建非条件设置,它就会删除所有以前的设置。它甚至有评论。

if (!call.IsConditional)
            {
                lock (calls)
                {
                    // if it's not a conditional call, we do
                    // all the override setups.
                    // TODO maybe add the conditionals to other
                    // record like calls to be user friendly and display
                    // somethig like: non of this calls were performed.
                    if (calls.ContainsKey(key))
                    {
                        // Remove previous from ordered calls
                        InterceptionContext.RemoveOrderedCall(calls[key]);
                    }

                    calls[key] = call;
}

关于c# - Mock 上的设置未返回预期值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36644721/

相关文章:

c# - Windows Phone 7 的目录中可以存储的最大文件数?

c# - 工作单元 + 存储库模式 : The Fall of the Business Transaction Concept

c# - 即使是简单的起订量代码也会抛出 NotSupportedException

c# - 为什么 HttpContext 为空?

c# - 在 C# 中使用嵌套在泛型类中的类作为类型参数

c# - 拦截文件流…是不可能的吗?

java - @MockBean 不适用于 JUnit5 和 Spring Boot 2 的 @WebMvcTest?

unit-testing - IntelliJ 中 Spring Boot 的 Bean 扫描

java - 如何使assertEquals方法中的预期对象成为一个姿势(在函数中,请参阅下面的代码)而不是整数或 double ?

c# - 如何对可空类型使用 Mock 设置