【问题标题】:NSubstitute: Received Calls asserts wronglyNSubstitute:已接来电断言错误
【发布时间】:2017-02-14 08:17:38
【问题描述】:

我创建了这个测试:

[TestFixture]
public class UsersTests
{
    private Core.Kernel coreKernel;
    private Core.Configuration.ICoreConfiguration coreConfiguration;

    [SetUp]
    public void SetUp()
    {
        this.coreConfiguration = NSubstitute.Substitute.For<Core.Configuration.ICoreConfiguration>();
        this.coreKernel = NSubstitute.Substitute.For<Core.Kernel>(this.coreConfiguration);

        this.coreKernel.Initialize();
    }

    [Test]
    public void AddUserTest()
    {
        Core.Communication.Entities.UserIdentity receivedUserIdentity = new Core.Communication.Entities.UserIdentity("user1", "passwd1");

        ((Core.Communication.ICoreService)this.coreKernel).AddUserIdentity(receivedUserIdentity);
        this.coreKernel.Received(100).AddUser(Arg.Is<Core.Identity.UserIdentity>(u => u.UserId.Equals(receivedUserIdentity.UserId)));
    }
}

Core.Kernel 在哪里:

public partial class Kernel : Core.IKernel
{
    public Kernel(Configuration.ICoreConfiguration configuration)
            : this(configuration, null, Enumerable.Empty<Type>())
    {

    }

    public Kernel(Configuration.ICoreConfiguration configuration, Communication.ICoreService service, IEnumerable<Type> producerTypes)
    {
        if (configuration == null)
            throw new ArgumentException("configuration object must be provided", "configuration");

        if (producerTypes.Any(t => !t.IsAssignableFrom(typeof(Core.Extensibility.AbstractProducerPlugin))))
            throw new ArgumentException("All types must inherit from AbstractProducerPlugin", "plugins");


        this.state = KernelState.initializing;

        this.configuration = configuration;
        this.service = service ?? this;
        this.producerTypes = producerTypes;

        this.backends = new Dictionary<Core.Identity.DomainIdentity, Backend.Infrastructure.IBackend>();
    }

    internal virtual void AddUser(Core.Identity.UserIdentity userIdentity) {...}
}

尽管如此,this.coreKernel.Received(100).AddUser(... 没有被调用 100 次,只有一次。我做错了什么?

我的意思是,我不想给AddUser 打 100 次电话。我正在检查 AddUser 应该被调用 100 次。所以,断言应该失败。

编辑

猜猜这段代码(Core.IKernel.AddUserIdentity(...) 实现):

public class Core.Kernel {
    public override void Core.IKernel.AddUserIdentity(UserIdentity userIdentity) {
        this.AddUser(userIdentity); <<----- AddUser(...) is called
    }
}

我认为这个问题与:

  1. Core.Kernel 实现 Core.IKernelCore.IKernelAddUserIdentity(...) 方法。
  2. 我在嘲笑 Core.Kernel 而不是在嘲笑 Core.IKernel
  3. 根据Core.IKernel.AddUserIdentity(...)方法实现AddUser应该没达到。
  4. AddUserCore.Kernelinternal virtual 方法。它不是任何方法接口的实现。

我想断言AddUser 在达到AddUserIdentity 时被调用一次。

关于模拟的其他问题:

  1. For&lt;T&gt; 其中 T 是一个具体的类 -> virtual 方法被替换了吗?没有执行virtual 方法?
  2. ForPartsOf&lt;T&gt; 其中 T 是一个具体的类 -> 这个类的哪些部分被模拟了(virtual methods,重写的接口方法)?

【问题讨论】:

  • 我无法从这段代码中判断为什么断言没有失败,但我想我应该提到你似乎正在替代Core.Kernel,但想测试其中的一些逻辑。例如,您在替代上调用coreKernel.Initialise()AddUserIdentity(...),如果它是virtual,则不会运行任何实际逻辑。您可能需要查看partial substitutes 上的文档以实现此目的。或者更好的是,重构设计以允许您新建一个真正的 Core.Kernel 并测试它与其依赖项的交互。
  • 感谢大卫的 cmets。你能看一下帖子吗?我已经对其进行了编辑以添加一些细节。

标签: nsubstitute


【解决方案1】:

它只被调用一次,因为你只调用了一次AddUserReceived 断言检查它被调用了多少次,它不会告诉 NSubstitue 调用你的方法 100 次,你需要手动执行 :)

NSubstitute 还为您提供了通过将整数传递给 Received() 来断言接收到特定数量的呼叫的选项。如果替代品没有收到那么多匹配的调用,这将抛出

http://nsubstitute.github.io/help/received-calls/

【讨论】:

  • 感谢 user9993 的评论。我了解代码的作用,但是,断言应该失败,但它成功了。 AddUser 应该在执行完AddUserIdentity 后调用一次。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-08
  • 2018-05-19
相关资源
最近更新 更多