You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何断言NSubstitute替代对象收到含指定列表参数的调用?

没问题,我来帮你搞定这个测试场景!针对用Caliburn.Micro EventAggregator发布的ExampleEvent,我们可以用NUnit+NSubstitute轻松验证事件里的整数列表是否符合预期。

先补全必要的代码定义

首先,把你提到的ExampleEvent补全完整:

public class ExampleEvent
{
    // 确保属性是可访问的,方便测试验证
    public List<int> SampleValues { get; set; } = new List<int>();
}

假设我们有一个依赖IEventAggregator的类(比如ViewModel),它包含触发事件发布的逻辑:

public class MyViewModel
{
    private readonly IEventAggregator _eventAggregator;

    public MyViewModel(IEventAggregator eventAggregator)
    {
        _eventAggregator = eventAggregator;
    }

    // 这个是我们要测试的方法:发布包含特定整数列表的事件
    public async Task PublishSampleEvent()
    {
        var sampleEvent = new ExampleEvent
        {
            SampleValues = new List<int> { 2, 4, 6 } // 假设这是业务逻辑生成的列表
        };
        // 用Caliburn.Micro的异步发布方法(根据你用的版本,也可能是PublishAsync)
        await _eventAggregator.PublishOnUIThreadAsync(sampleEvent);
    }
}

编写测试代码

接下来是核心的测试逻辑,我们要验证:当调用PublishSampleEvent时,EventAggregator确实发布了带有预期整数列表的ExampleEvent。

using NUnit.Framework;
using NSubstitute;
using Caliburn.Micro;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

[TestFixture]
public class MyViewModelTests
{
    private IEventAggregator _mockEventAggregator;
    private MyViewModel _testViewModel;

    [SetUp]
    public void SetupTest()
    {
        // 用NSubstitute创建EventAggregator的模拟对象
        _mockEventAggregator = Substitute.For<IEventAggregator>();
        // 注入模拟对象,实例化被测试的ViewModel
        _testViewModel = new MyViewModel(_mockEventAggregator);
    }

    [Test]
    public async Task PublishSampleEvent_ShouldSendEventWithExpectedIntegerList()
    {
        // 定义我们预期的整数列表
        var expectedValues = new List<int> { 2, 4, 6 };

        // 执行要测试的方法
        await _testViewModel.PublishSampleEvent();

        // 关键验证步骤:
        // 1. 确认EventAggregator的Publish方法被调用了1次
        // 2. 验证传入的ExampleEvent的SampleValues和预期列表完全匹配(用SequenceEqual做值比较)
        _mockEventAggregator.Received(1)
            .PublishOnUIThreadAsync(Arg.Is<ExampleEvent>(e => 
                e.SampleValues.SequenceEqual(expectedValues)));
    }
}

几个关键要点说明

  • 模拟EventAggregator:用NSubstitute的Substitute.For<IEventAggregator>()可以让我们完全控制这个依赖,跟踪它的调用行为,不用依赖真实的EventAggregator实例。
  • 值比较的坑:直接用e.SampleValues == expectedValues是不行的,因为List是引用类型,这里要用SequenceEqual来比较两个列表的元素是否完全一致(顺序和值都要匹配)。
  • 异步处理:如果你的发布方法是异步的(比如用PublishOnUIThreadAsync),测试方法要加上async并await触发方法,确保事件发布逻辑执行完成后再做验证。

内容的提问来源于stack exchange,提问作者GnUfTw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:56:56