如何使用异步调用对Prism INavigationAware.OnNavigatedTo进行单元测试

时间:2020-09-03 12:10:42

标签: c# unit-testing mvvm xamarin.forms prism

我们的许多ViewModel-Unit-Tests在Arrange-Phase中创建一个ViewModel,在Act-Phase中调用OnNavigatedTo(),并声明OnNavigatedTo完成后应该发生的某些事情(例如,某些Properties包含某些值)。

当OnNavigatedTo()的实现包含异步方法调用(例如从后端加载数据)时,我们会遇到一个问题,因为OnNavigatedTo返回void,我们无法等待其完成。

在单元测试中,我们模拟了对后端的调用,因此它们立即返回,并且问题几乎从未出现。但是,在某些情况下,正是这种情况导致了构建服务器上的问题(在Linux上运行),我怀疑这总是会产生一种竞态条件,而这种竞态条件在大多数情况下都是偶然起作用的。

我们想到的一种解决方法是提供一个返回Task的公共方法,该方法包含OnNavigatedTo的实现并供单元测试使用,但通常不建议仅针对以下情况扩展被测系统的公共API表面:为了测试。

将所有代码移到IInitializeAsync.InitializeAsync在我看来不是一种选择,并且这两个生命周期钩子并不等效,并且可能不会在每次页面导航中都调用InitializeAsync。

所以我的问题是:我们如何在进行异步调用的INavigationAware.OnNavigatedTo中可靠地对代码进行单元测试?

1 个答案:

答案 0 :(得分:1)

我们想到的一种解决方法是提供一个返回Task的公共方法,该Task包含OnNavigatedTo的实现,并由单元测试使用

除了使用internal(如果夹具必须在另一个装配中,请使用InternalsVisibleTo)或什至private(如果您可以制作{固定一个嵌套类)。

或者,定义自己的INavigatedToAsyncForTest(使用返回Task的方法)并显式实现以限制这些方法的可发现性。

但是,仅出于测试目的,扩展受测系统的公共API表面通常不是一个好主意。

是的,但是使方法internal尖叫“这不是公共API”,尤其是当类型本身是internal时(应该使用哪种视图模型,除非您必须将视图放在不同的视图中)。组装),因此您可以在某种程度上减轻这种情况。