【发布时间】:2020-02-26 13:20:47
【问题描述】:
我正在使用 xUnit 和 ReactiveUI 11.2(对于 WPF,.NET Framework 4.8,但我认为我的问题更笼统)。
基本上,我想在 ViewModel 中测试我的 ReactiveCommand。
例如,有一些条件在我的代码中引发了异常,我的程序崩溃了。
我想做一个单元测试来重现这个错误(单元测试应该失败),然后我会修复我的错误,以某种方式防止异常,然后我的测试应该通过以反映修复。 (相当标准的程序)。
问题是,在 ReactiveCommand 期间抛出的任何异常似乎都被 ReactiveUI “吞噬”了,异常不会使测试失败。
此外,如果我尝试在 .Subscribe() 的回调中编写 Assert() 语句,也会发生同样的情况:我可以在调试期间看到我的断言正确失败,但无论如何测试都以绿色标记为“通过”。
我尝试了不同的方式,与调度程序一起玩了一下,但没有任何改进。 我尝试使用所描述的“.ThrownExceptions”也无济于事。
这里有一些文档:https://reactiveui.net/docs/handbook/testing/
TL;DR
如何在我的ReactiveCommands 中设置异常导致我的单元测试失败?我应该如何完全对ReactiveCommands 进行单元测试?
以下是演示该问题的完整程序。
与 NuGet 包一起使用: xunit 2.4.1, xunit.runner.visualstudio 2.4.1, ReactiveUI.Testing 11.2.1
using Microsoft.Reactive.Testing;
using ReactiveUI;
using ReactiveUI.Testing;
using System;
using System.Reactive;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using Xunit;
namespace Tests
{
public class Foo
{
public ReactiveCommand<Unit, Unit> TestCommand { get; }
public Foo(IScheduler? scheduler = null)
{
scheduler ??= RxApp.MainThreadScheduler;
TestCommand = ReactiveCommand.Create(Explode, canExecute: null, outputScheduler: scheduler);
}
public void Explode()
{
throw new Exception("Boom");
}
}
public class ReactiveCommandTests
{
// Should fail? (it doesn't fail)
[Fact]
public void Test1()
{
var foo = new Foo();
foo.TestCommand.Execute().Subscribe();
}
// Should fail (it fails alright ! no ReactiveUI Observable here...)
[Fact]
public void Test2()
{
var foo = new Foo();
foo.Explode();
}
// Should fail? (it doesn't fail)
[Fact]
public void Test3()
{
var testScheduler = new TestScheduler();
var foo = new Foo(testScheduler);
foo.TestCommand.Execute().Subscribe();
}
// Should fail? (it doesn't fail)
[Fact]
public void Test4()
{
new TestScheduler().With(scheduler =>
{
var foo = new Foo(scheduler);
foo.TestCommand.Execute().Subscribe();
});
}
// Should fail ? (it doesn't fail)
[Fact]
public void Test5()
{
var foo = new Foo();
foo.TestCommand.ThrownExceptions.Subscribe(
(ex) => {
Console.WriteLine("Exception detected !");
Assert.False(true); // This is hit, but doesn't even make the test fail....
});
foo.TestCommand.Execute().Subscribe();
}
}
}
所有测试都会引发异常,所有测试都应该失败 IMO,但只有一个不使用 `ReactiveCommand 失败。
【问题讨论】:
-
我相信你可以使用
await。IObservable可等待。 -
@Aluan Haddad,谢谢,但无法编译。
IObservable<Foo> does not contain a definition for 'GetAwaiter' ... -
应该...你运行的是哪个版本?
-
@AluanHaddad 我可以看到
System.Reactive 4.3.2作为 ReactiveUI 的依赖项 -
@AluanHaddad 我刚刚注意到
IObservable<T>是在 vanilla .NET 框架 (4.8) 的 System 命名空间中定义的。而且它看起来并不“等待”,它只是继承自IDisposable。
标签: c# unit-testing xunit reactiveui