我在.Net 4.0上使用PRISM和autofac for WPF,我想开发一个可测试的ViewModels。为了测试我们使用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。
答案 0 :(得分:0)
最简单的答案是插入一个&#39;似乎&#39; (请参阅Michael Feathers的“有效使用遗留代码”)围绕静态类InteractionRequest<SaveBrowserDialogViewModel>
。
这意味着将其推送到接口(和实现)之后,然后使用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);
}
}