使用MVVM Light和DispatcherHelper进行单元测试

4

我有一个使用MVVM Light Toolkit的SL4应用程序。在视图模型中,我调用一个数据服务,该服务从OData服务中检索数据。在VM中,我使用DispatcherHelper工具类( MVVM Light的一部分)从传递给数据服务的回调中更新VM上属性。例如,我的视图模型方法如下:

public string CurrentUserLogin {
  get {
    if (string.IsNullOrEmpty(_currentUserLogin))
      RetrieveCurrentUserLogin();
    return string.IsNullOrEmpty(_currentUserLogin) ? _currentUserLogin : _currentUserLogin.Replace(@"\\", @"\");
  }
  set {
    if (_currentUserLogin != value) {
      _currentUserLogin = value;
      RaisePropertyChanged(CurrentUserLoginPropertyName);
    }
  }
}

private void RetrieveCurrentUserLogin() {
  DataService.GetCurrentUserLogin(result => {
    DispatcherHelper.UIDispatcher.BeginInvoke(() => {
      CurrentUserLogin = result;
    });
  });
}

这是我的数据服务的样子:

public void GetCurrentUserLogin(Action<string> callback) {
  // create query request
  var query = OnDemandContext.CreateQuery<string>("GetCurrentUserLogin");
  var request = (HttpWebRequest)WebRequest.Create(query.RequestUri);
  request.BeginGetResponse(asyncResult => {
    var responseStream = request.EndGetResponse(asyncResult).GetResponseStream();
    var responseDocument = XDocument.Load(responseStream);
    callback(responseDocument.Root.Value);
  }, null);
}

当我运行我的SL应用程序时,一切都很好。然而,当我尝试使用SL单元测试框架编写单元测试时,出现了问题。我可以测试我的数据服务,但似乎DispatcherHelper在所有测试中都会出现问题,因为当触发DispatcherHelper.UIDispatcher时,它总是为空。我认为这与初始化有关(在我的SL应用程序的Application_Startup()中)。我尝试在我的测试应用程序中初始化它,但没有帮助。我还尝试使用DispatcherHelper.CheckBeginInvokeOnUI(),但对问题没有影响。
有什么想法吗?
1个回答

4

您好,

我刚刚创建了一个简单的SL UT项目,并且我是在App.XAML.CS文件中完成的。

private void Application_Startup(object sender, StartupEventArgs e)
{
  RootVisual = UnitTestSystem.CreateTestPage();
  DispatcherHelper.Initialize();
}

接下来我将其设置为测试(在tests.cs中):

[TestMethod]
public void TestMethod1()
{
   Assert.IsNotNull(DispatcherHelper.UIDispatcher, "UI Dispatcher should not be null");

   DispatcherHelper.CheckBeginInvokeOnUI(() =>
   {
       // Do nothing
       var x = 1;
   });
}

这对我有用。我甚至在“var x = 1;”上设置了断点,它也触发了断点。这解决了你的问题吗?(如果是,请将其标记为答案)。


谢谢DevTheo,你的解决方案有效,但那并不是问题的根本。测试项目正在测试另一个项目中的视图模型。DispatcherHelper在另一个项目中。我在原始问题中拥有的代码片段驻留在视图模型中,我想在单元测试中覆盖它。我尝试将DispatcherHelper.Initialize()放入测试项目中,但它没有起作用。 - Andrew Connell
1
我再试一次...但我必须相信,如果你在其中一个项目中初始化了DispatcherHelper,它应该在两个项目中都能工作...也许我错了...也许它附加到App上...但当前的应用程序是测试项目...嗯... - DevTheo
1
它应该可以工作,因为DispatcherHelper静态地存储了主线程的调度程序。听起来你确实是太晚初始化DispatcherHelper了。尝试确保在使用UIDispatcher属性之前调用Initialize方法。干杯。 - LBugnion
于是我回头在我的单元测试中加入了Initialize()调用,就在调用使用DispatcherHelper的getter加载数据的ViewModel属性之前立即进行。当我逐步执行时,我发现它说UIDispatcher不再为null……不确定之前错在哪里。然而,我看不到它是否真正修复了问题,因为我的测试显示出现了异常,但没有处理。似乎无法找到这是发生在哪里,因为它使我的测试结果不确定...有什么想法吗? - Andrew Connell
感谢您的评论,我的DispatchHelper在初始化之前无法正常工作。 - strattonn
SL UT是Silverlight Unit Test的不幸缩写。 - dBlisse

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接