【问题标题】:How to make InteractionRequest in ViewModel testable?如何使 ViewModel 中的 InteractionRequest 可测试?
【发布时间】:2014-07-25 14:58:19
【问题描述】:

我在 .Net 4.0 上为 WPF 使用 PRISM 和 autofac,我想开发一个可测试的 ViewModel。为了进行测试,我们使用 nUnit 和 moq 进行模拟。

所以我有课:

public class BackupViewModel : InteractionRequestNotificationObject
   {
      private readonly DelegateCommand backupCommand;
      private readonly IBackupCommandService commandService;
      private readonly InteractionRequest<SaveBrowserDialogViewModel> saveDialogRequest = new InteractionRequest<SaveBrowserDialogViewModel>();

      public BackupViewModel(IBackupCommandService commandService, ISaveBrowserDialogViewModel saveBrowserDialog)
      {
          if(commandService == null)
              throw new ArgumentNullException("commandService"); 
          if(saveBrowserDialog == null)
              throw new ArgumentNullException("saveBrowserDialog");

          this.commandService = commandService;
          this.saveBrowserDialog = saveBrowserDialog;
          this.backupCommand = new DelegateCommand(Backup);
      }

      private void Backup()
      {
          saveBrowserDialog.Filters = "Zip archive (*.zip)|*.zip";
          saveDialogRequest.Raise((SaveBrowserDialogViewModel)saveBrowserDialog);
          if (saveBrowserDialog.Confirmed)
          {
              commandService.BackupDatabase(saveBrowserDialog.Path);
          }
      }
   }

我已经写了单元测试:

[TestFixture]
public class BackupViewModelTests
{
    private BackupViewModel sut;
    private Mock<IBackupCommandService> backupCommandServiceMock;
    private Mock<ISaveBrowserDialogViewModel> saveDialogMock;

    [SetUp]
    public void Setup()
    {
        backupCommandServiceMock = new Mock<IBackupCommandService>();
        saveDialogMock = new Mock<ISaveBrowserDialogViewModel>();
        sut = new BackupViewModel(backupCommandServiceMock.Object, saveDialogMock.Object);
    }

    [Test]
    public void BackupViewModelShouldCallBackupFromCommandService()
    {
        saveDialogMock.Setup(x => x.Confirmed).Returns(true);
        sut.BackupCommand.Execute(null);
        backupCommandServiceMock.Verify(x => x.BackupDatabase(It.IsAny<string>()),Times.Once());
    }
}

现在我还不知道如何模拟 saveDialogRequest.Raise(..) 以便它可以用于模拟对象,而不是真正的 SaveBrowserDialogViewModel。

【问题讨论】:

    标签: c# wpf unit-testing moq


    【解决方案1】:

    最简单的答案是在静态类 InteractionRequest&lt;SaveBrowserDialogViewModel&gt; 周围插入一个“似乎”(请参阅​​ Michael Feathers 的有效处理遗留代码)。

    这意味着将它推到一个接口(和实现)后面,然后用 AutoFac 注册这个接口和实现,然后将一个实例作为构造函数参数传递给 ViewModel 类。这将允许您在测试中模拟接口。

    类似这样的:

    public interface IInteractionRequestWrapper<T>
    {
        void Request(T instance);
    }
    
    public class InteractionRequestWrapper<T> : IInteractionRequestWrapper<T>
    {
        private InteractionRequest<T> _saveDialogRequest;
    
        public InteractionRequestWrapper()
        {
            _saveDialogRequest = new InteractionRequest<T>();
        }
        public void Request(T instance)
        {
            _saveDialogRequest.Request(instance);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-27
      • 1970-01-01
      • 2019-10-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多