如何断言替代品收到了带有给定列表的调用作为参数?
How to assert that substitute received a call with a given list as it's argument?
我正在结合使用 NUnit 和 NSubstitute 来测试应用程序。该应用程序使用 Caliburn.Micro MVVM 框架。考虑以下我想为其创建测试的示例代码。它利用 Caliburn Micro 的事件聚合器 class 来发布消息。我想验证在此代码中发布的事件是否确实包含我期望的整数列表(如下面测试代码中的注释所示)。
public class ExampleEvent
{
List<int> SampleValues { get; set; }
}
public class ExampleClass
{
private IEventAggregator _eventAggregator;
public ExampleClass(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator
}
public void ExampleMethod()
{
var exampleArray = new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
_eventAggregator.PublishOnUIThread(new 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 } )))
}
}
如何正确地完成这一任务?
PublishOnUIThread
is an extension method that is called on IEventAggregator.Publish
。
/// <summary>
/// Publishes a message on the UI thread.
/// </summary>
/// <param name="eventAggregator">The event aggregator.</param>
/// <param name = "message">The message instance.</param>
public static void PublishOnUIThread(this IEventAggregator eventAggregator, object message) {
eventAggregator.Publish(message, Execute.OnUIThread);
}
因此您需要模拟 IEventAggregator.Publish
以验证您的测试是否按预期进行。
_eventAggregator.Received().Publish(Arg.Any<ExampleEvent>(), Arg.Any<Action<System.Action>>());
我的问题源于没有意识到数组不会相互比较相等,即使它们具有相同的元素。我能够检查事件聚合器是否收到了对具有预期参数的 PublishOnUIThread() 方法的调用,如下所示。
_eventAggregator.Received().PublishOnUIThread(Arg.Is<StageOneSamplesAvailableEvent>(message => message.Samples.SequenceEqual(new List<double> { 10, 10, 10, 0, 0, 0, 0, 0 })));
作为,请注意这里的扩展方法
就使用的列表断言而言,有几个选项。 This answer uses SequenceEqual
with Arg.Is
to check the items are equal. Or you can use a custom extension. There is also an experimental API (subject to change) in NSubstitute that can let you define more involved argument matchers, including incorporating existing assertion frameworks.
最后,我有时发现仅 store the argument used 并使用您最喜欢的单元 test/assertion 框架进行断言是最简单的。例如:
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);
我正在结合使用 NUnit 和 NSubstitute 来测试应用程序。该应用程序使用 Caliburn.Micro MVVM 框架。考虑以下我想为其创建测试的示例代码。它利用 Caliburn Micro 的事件聚合器 class 来发布消息。我想验证在此代码中发布的事件是否确实包含我期望的整数列表(如下面测试代码中的注释所示)。
public class ExampleEvent
{
List<int> SampleValues { get; set; }
}
public class ExampleClass
{
private IEventAggregator _eventAggregator;
public ExampleClass(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator
}
public void ExampleMethod()
{
var exampleArray = new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
_eventAggregator.PublishOnUIThread(new 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 } )))
}
}
如何正确地完成这一任务?
PublishOnUIThread
is an extension method that is called on IEventAggregator.Publish
。
/// <summary>
/// Publishes a message on the UI thread.
/// </summary>
/// <param name="eventAggregator">The event aggregator.</param>
/// <param name = "message">The message instance.</param>
public static void PublishOnUIThread(this IEventAggregator eventAggregator, object message) {
eventAggregator.Publish(message, Execute.OnUIThread);
}
因此您需要模拟 IEventAggregator.Publish
以验证您的测试是否按预期进行。
_eventAggregator.Received().Publish(Arg.Any<ExampleEvent>(), Arg.Any<Action<System.Action>>());
我的问题源于没有意识到数组不会相互比较相等,即使它们具有相同的元素。我能够检查事件聚合器是否收到了对具有预期参数的 PublishOnUIThread() 方法的调用,如下所示。
_eventAggregator.Received().PublishOnUIThread(Arg.Is<StageOneSamplesAvailableEvent>(message => message.Samples.SequenceEqual(new List<double> { 10, 10, 10, 0, 0, 0, 0, 0 })));
作为
就使用的列表断言而言,有几个选项。 This answer uses SequenceEqual
with Arg.Is
to check the items are equal. Or you can use a custom extension. There is also an experimental API (subject to change) in NSubstitute that can let you define more involved argument matchers, including incorporating existing assertion frameworks.
最后,我有时发现仅 store the argument used 并使用您最喜欢的单元 test/assertion 框架进行断言是最简单的。例如:
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);