C# 如何断言替换接收到的调用具有给定列表,因为它';谁的论点?

C# 如何断言替换接收到的调用具有给定列表,因为它';谁的论点?,c#,unit-testing,nunit,caliburn.micro,nsubstitute,C#,Unit Testing,Nunit,Caliburn.micro,Nsubstitute,我将NUnit与NSubstitute结合使用来测试应用程序。该应用程序使用Caliburn.Micro MVVM框架。请考虑下面的示例代码,我想为其创建一个测试。它利用Caliburn Micro的事件聚合器类发布消息。我想验证此代码中发布的事件是否确实包含我期望的整数列表(如下面测试代码中的注释所示) 公共类示例事件 { 列出采样值{get;set;} } 公共类示例类 { 私人事件聚合器; 公共示例类(IEventAggregator事件聚合器) { _eventAggregator=ev

我将NUnit与NSubstitute结合使用来测试应用程序。该应用程序使用Caliburn.Micro MVVM框架。请考虑下面的示例代码,我想为其创建一个测试。它利用Caliburn Micro的事件聚合器类发布消息。我想验证此代码中发布的事件是否确实包含我期望的整数列表(如下面测试代码中的注释所示)

公共类示例事件
{
列出采样值{get;set;}
}
公共类示例类
{
私人事件聚合器;
公共示例类(IEventAggregator事件聚合器)
{
_eventAggregator=eventAggregator
}
public void ExampleMethod()
{
var exampleArray=新列表{1,2,3,4,5,6,7,8,9};
_eventAggregator.PublishOnIthread(新的ExampleEvent{SampleValues=exampleArray});
}
}
上面代码的测试可能如下所示

[TestFixture]
public class ExampleClassTests()
{
    private ExampleClass _uut;
    private IEventAggregator _eventAggregator;

    [SetUp]
    public void SetUp()
    {
        _eventAggregator = Substitute.For<IEventAggregator>();
        _uut = new ExampleClass(_eventAggregator);
    }

    [Test]
    public void ExampleMethod_ShouldRaiseEvent()
    {
        _uut.ExampleMethod();

        // I would like to add something like the line below but errors are thrown when it is executed...
        _eventAggregator.Received().PublishOnUIThread(Arg.Is<ExampleEvent>(x => x.SampleValues.Equals( new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8, 9 } )))
    }
}
[TestFixture]
公共类ExampleClassTests()
{
私有示例类;
私人事件聚合器;
[设置]
公共作废设置()
{
_eventAggregator=替换.For();
_uut=新的ExampleClass(\u eventAggregator);
}
[测试]
public void示例方法\u ShouldRaiseEvent()
{
_uut.ExampleMethod();
//我想添加一些类似下面这行的内容,但在执行时会抛出错误。。。
_eventAggregator.Received().PublishOnIthread(Arg.Is(x=>x.SampleValues.Equals)(新列表{1,2,3,4,5,6,7,8,9})))
}
}
如何才能正确地实现这一点?

是一种被调用的扩展方法

是在上调用的扩展方法


我的问题源于没有意识到数组之间的比较是不相等的,即使它们具有相同的元素。我能够检查事件聚合器是否接收到对PublishOnUIThread()方法的调用,所需参数如下

_eventAggregator.Received().PublishOnUIThread(Arg.Is<StageOneSamplesAvailableEvent>(message => message.Samples.SequenceEqual(new List<double> { 10, 10, 10, 0, 0, 0, 0, 0 })));
\u eventAggregator.Received().publisonuithread(Arg.Is(message=>message.Samples.SequenceEqual(新列表{10,10,0,0,0,0}));

我的问题源于没有意识到数组之间的比较是不相等的,即使它们有相同的元素。我能够检查事件聚合器是否接收到对PublishOnUIThread()方法的调用,所需参数如下

_eventAggregator.Received().PublishOnUIThread(Arg.Is<StageOneSamplesAvailableEvent>(message => message.Samples.SequenceEqual(new List<double> { 10, 10, 10, 0, 0, 0, 0, 0 })));
\u eventAggregator.Received().publisonuithread(Arg.Is(message=>message.Samples.SequenceEqual(新列表{10,10,0,0,0,0}));
同样,请注意此处的扩展方法

在所用列表上的断言方面,有几个选项。使用
SequenceEqual
Arg.Is
检查项目是否相等。或者你也可以用一个。NSubstitute中还有一个实验性API(可能会有变化),可以让您定义更复杂的参数匹配器,包括

最后,我有时发现,使用您最喜欢的单元测试/断言框架进行测试和断言是最容易的。例如:

ExampleEvent eventPublished = null;
eventAggregator.Publish(Arg.Do<ExampleEvent>(x => eventPublished = x), Arg.Any<Action<System.Action>>());

//ACT
_uut.ExampleMethod();

//ASSERT
MyTestFramework.Assert.CollectionsEqual(
    new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8, 9 },
    eventPublished.Samples);
exampleEventPublished=null;
eventAggregator.Publish(Arg.Do(x=>eventPublished=x),Arg.Any());
//表演
_uut.ExampleMethod();
//断言
MyTestFramework.Assert.CollectionsEqual(
新名单{1,2,3,4,5,6,7,8,9},
(a)样本;
同样,请注意此处的扩展方法

在所用列表上的断言方面,有几个选项。使用
SequenceEqual
Arg.Is
检查项目是否相等。或者你也可以用一个。NSubstitute中还有一个实验性API(可能会有变化),可以让您定义更复杂的参数匹配器,包括

最后,我有时发现,使用您最喜欢的单元测试/断言框架进行测试和断言是最容易的。例如:

ExampleEvent eventPublished = null;
eventAggregator.Publish(Arg.Do<ExampleEvent>(x => eventPublished = x), Arg.Any<Action<System.Action>>());

//ACT
_uut.ExampleMethod();

//ASSERT
MyTestFramework.Assert.CollectionsEqual(
    new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8, 9 },
    eventPublished.Samples);
exampleEventPublished=null;
eventAggregator.Publish(Arg.Do(x=>eventPublished=x),Arg.Any());
//表演
_uut.ExampleMethod();
//断言
MyTestFramework.Assert.CollectionsEqual(
新名单{1,2,3,4,5,6,7,8,9},
(a)样本;

我喜欢存储使用的参数,然后在以后对其进行断言,这似乎很灵活。另外,感谢你重申NKosi关于PublishOnIthread是一种扩展方法的观点,因为我现在意识到扩展方法是静态的,因此不能被嘲笑,至少是微不足道的。我喜欢存储使用的参数,然后在以后对其进行断言的想法,这似乎很灵活。另外,感谢你重申NKosi关于PublishOnIthread是一种扩展方法的观点,因为我现在意识到扩展方法是静态的,因此不能被嘲笑,至少是微不足道的。
ExampleEvent eventPublished = null;
eventAggregator.Publish(Arg.Do<ExampleEvent>(x => eventPublished = x), Arg.Any<Action<System.Action>>());

//ACT
_uut.ExampleMethod();

//ASSERT
MyTestFramework.Assert.CollectionsEqual(
    new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8, 9 },
    eventPublished.Samples);