【发布时间】:2021-11-01 07:21:17
【问题描述】:
背景
我有一个 ViewModel,我想使用 Visual Studio 的内置测试框架对其进行单元测试。
public async Task RefreshEntries(string rootID)
{
_isCurrentlyFetchingEntries = true;
if (_entriesCollectionSource == null)
_entriesCollectionSource = new ObservableCollection<ExplorerDisplayEntryDTO>();
_entriesCollectionSource.Clear();
Entries = CollectionViewSource.GetDefaultView(_entriesCollectionSource);
var entries = await Task.Run(() =>
{
var toReturn = (...) // Fetch plenty of things in my repo
return toReturn;
});
foreach (var entry in entries)
{
_entriesCollectionSource.Add(entry);
}
Entries.Filter = _customizedFilter;
_isCurrentlyFetchingEntries = false;
}
我编写了一个单元测试,它将间接await 这个特定任务(通过围绕 ViewModel 的多次调用)。
当运行单元测试时,(CTRL+R,T)它没有问题地通过。
调试单元测试时,上面sn-p第16行抛出异常
当运行程序正常(调试和发布模式)时,该方法不会触发任何错误。
System.NotSupportedException 这种类型的 CollectionView 不支持从不同于 Dispatcher 线程的线程更改其 SourceCollection
我查看了并行堆栈窗口,似乎在正常运行时(我怀疑在运行单元测试时),该行由主线程执行。而它似乎在调试测试时由其他线程执行。
问题
运行单元测试与调试单元测试相比,我应该期待什么样的行为变化?
【问题讨论】:
-
您是否在 STAThread 中运行测试?您使用的是 WPF 应用程序对象吗?尝试将 GetDefaultView 行放在 Filter 行之前。我的猜测是,在调试器之外运行时也存在该错误;只是没有报道。我添加了一个 WPF 标签。
-
如果你的 Task.Run 上有一个
ConfigureAwait(false)就会有这个问题。 -
好吧,我没有注意到在运行测试而不是调试它时吞下了异常。所以它可能在测试运行期间抛出(如你所说),但在测试调试期间明确提出。我尝试在测试中添加
[STAThread]注解,并添加ConfigureAwait(false)但调试时仍然抛出异常。 -
你能展示一下测试的代码吗?
-
在缩小我的测试代码以找出导致上述代码的确切指令时,我发现我向
INotifyPropertyChanged的PropertyChanged注册了一个async void方法。然后,此方法将调用上面显示的代码。我会深入研究,因为我怀疑这可能导致至少部分问题。如果我怀疑是真的,将更新问题/发布答案。
标签: c# wpf asynchronous mstest