如何使用异步调用对 Prism INavigationAware.OnNavigatedTo 进行单元测试
How to unit test Prism INavigationAware.OnNavigatedTo with async calls
我们的很多 ViewModel-Unit-Tests 在 Arrange-Phase 中创建一个 ViewModel,在 Act-Phase 中调用 OnNavigatedTo() 并断言一些应该在 OnNavigatedTo 完成后发生的事情(例如一些属性包含某些值).
当 OnNavigatedTo() 的实现包含异步方法调用(如从后端加载数据)时,我们会遇到问题,因为 OnNavigatedTo return无效,我们无法等待它完成。
在我们的单元测试中,我们模拟了对后端的调用,因此它们 return 立即出现,问题几乎从未出现过。然而,我们有一个案例正是这种情况在构建服务器上造成了问题(运行 on Linux),我怀疑这总是会产生一种竞争条件,这种情况在大多数情况下都是偶然发生的.
我们想出的一个解决方法是提供一个 public 方法 returning 一个任务,它包含 OnNavigatedTo 的实现并被单元测试使用,但扩展通常不是一个好主意public API 被测系统的表面只是为了测试。
在我看来,将所有代码移至 IInitializeAsync.InitializeAsync 不是一个选项,而且这 2 个生命周期挂钩并不等效,并且可能不会在每次页面导航时调用 InitializeAsync。
所以我的问题是:我们如何可靠地对 INavigationAware.OnNavigatedTo 中进行异步调用的代码进行单元测试?
One workaround we came up with was to provide a public method returning a Task which contains the implementation of OnNavigatedTo
and is used by the unit tests
我会完全这样做,除了我会使用 internal
(如果夹具必须在另一个组件中,则使用 InternalsVisibleTo
)甚至 private
(如果可以的话使夹具嵌套 class).
或者,定义您自己的 INavigatedToAsyncForTest
(使用 return Task
的方法)并明确实施它以限制这些方法的可发现性。
but it's generally no good idea to extend the public API surface of the system under test just for the sake of testing.
正确,但是使方法 internal
尖叫“这不是 public API”,特别是如果类型本身是 internal
(哪个视图模型应该是,除非你必须将你的观点放在不同的程序集中),所以你可以稍微减轻这种情况。
我们的很多 ViewModel-Unit-Tests 在 Arrange-Phase 中创建一个 ViewModel,在 Act-Phase 中调用 OnNavigatedTo() 并断言一些应该在 OnNavigatedTo 完成后发生的事情(例如一些属性包含某些值).
当 OnNavigatedTo() 的实现包含异步方法调用(如从后端加载数据)时,我们会遇到问题,因为 OnNavigatedTo return无效,我们无法等待它完成。
在我们的单元测试中,我们模拟了对后端的调用,因此它们 return 立即出现,问题几乎从未出现过。然而,我们有一个案例正是这种情况在构建服务器上造成了问题(运行 on Linux),我怀疑这总是会产生一种竞争条件,这种情况在大多数情况下都是偶然发生的.
我们想出的一个解决方法是提供一个 public 方法 returning 一个任务,它包含 OnNavigatedTo 的实现并被单元测试使用,但扩展通常不是一个好主意public API 被测系统的表面只是为了测试。
在我看来,将所有代码移至 IInitializeAsync.InitializeAsync 不是一个选项,而且这 2 个生命周期挂钩并不等效,并且可能不会在每次页面导航时调用 InitializeAsync。
所以我的问题是:我们如何可靠地对 INavigationAware.OnNavigatedTo 中进行异步调用的代码进行单元测试?
One workaround we came up with was to provide a public method returning a Task which contains the implementation of
OnNavigatedTo
and is used by the unit tests
我会完全这样做,除了我会使用 internal
(如果夹具必须在另一个组件中,则使用 InternalsVisibleTo
)甚至 private
(如果可以的话使夹具嵌套 class).
或者,定义您自己的 INavigatedToAsyncForTest
(使用 return Task
的方法)并明确实施它以限制这些方法的可发现性。
but it's generally no good idea to extend the public API surface of the system under test just for the sake of testing.
正确,但是使方法 internal
尖叫“这不是 public API”,特别是如果类型本身是 internal
(哪个视图模型应该是,除非你必须将你的观点放在不同的程序集中),所以你可以稍微减轻这种情况。