[英]How to execute C# wpf commands via a unit test
I'm fairly new to unit tests in general and C#, I'm trying to verify that once a command funs that a collection has the correct number of objects.我对一般的单元测试和 C# 相当陌生,我试图验证一旦一个命令有趣,一个集合具有正确数量的对象。 So the flow should be: Command excecutes -> method adds objects to collection -> Test checks collection has objects.
所以流程应该是:命令执行 -> 方法将对象添加到集合 -> 测试检查集合是否有对象。 When I try this the test throws the error "System.InvalidOperationException: The calling thread must be STA, because many UI components require this."
当我尝试这个时,测试会抛出错误“System.InvalidOperationException:调用线程必须是 STA,因为许多 UI 组件都需要这个。”
Since the command works fine in normal opperation I assume there is something about the way I have set up the testing that is incorrect.由于该命令在正常操作中运行良好,我认为我设置测试的方式有些不正确。 I Tried adding [STAThread] attribute to the testing method but still got the same error.
我尝试将 [STAThread] 属性添加到测试方法中,但仍然出现相同的错误。
My ViewModel to test我要测试的 ViewModel
namespace Space
{
public class SampleViewModel : ObservableObject, IPageViewModel
{
private string _id;
private string _initials;
private ObservableCollection<ISampleObject> _sampleModels;
private ICommand _validateId;
private IdValidator _idValidator;
public ViewModel(string initials)
{
Initials = initials;
}
public string Name
{
get { return "Sample"; }
}
public string Id
{
get
{
return _id;
}
set
{
if (value != _id)
{
_id = value;
OnPropertyChanged("Id");
}
}
}
public ObservableCollection<ISampleObject> SampleModels
{
get
{
if (_sampleModels == null)
{
_sampleModels = new ObservableCollection<ISampleObject>();
OnPropertyChanged("SampleModels");
}
return _sampleModels;
}
set
{
}
}
public IdValidator IdValidator
{
get
{
if (_idValidator == null)
{
_idValidator = new IdValidator();
OnPropertyChanged("IdValidator");
}
return _idValidator;
}
set { }
}
public ICommand ValidateIdCommand
{
get
{
if (_validateId == null)
{
_validateId = new RelayCommand(
param => ValidateId(AliquotId),
Predicate => AliquotId != ""
);
}
return _validateId;
}
}
/**
* <summary> This method checks the entered sample ID and attempts to categorise it
* and call the correct follow-up methods.
* </summary>
**/
private void ValidateId(string Id) // potentailly this should return a bool on successful/unsuccessful validation to make testing easier.
{
if (Id != null)
{
if (IdValidator.IsValidId(Id))
{
switch (IdValidator.ValidateId(AliquotId))
{
case IdType.Sample:
GetSample(Id);
break;
default:
break;
}
}
else
{
MessageBox.Show("Scanned Code not recognised", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
private void GetSample(string id)
{
SampleProvider sampleProvider = new SampleProvider();
SampleModel sampleModel = (SampleModel)sampleProvider .GetById(id);
if (!sampleModel.IsEnumPlate)
{
SampleModels.Add(sampleModel);
}
}
}
}
The testing code测试代码
namespace Space.Tests
{
[TestClass()]
public class SampleViewModelTests
{
ViewModel viewModel = new ViewModel("string") {
Id = "ID string"
};
[TestMethod()]
public void ViewModelTest_SampleModel_Retrieved()
{
viewModel.ValidateIdCommand.Execute(viewModel.Id);
Assert.IsTrue(viewModel.SampleModels.Count > 0);
}
}
}
'''
Calling Execute
is how you invoke the command:调用
Execute
是调用命令的方式:
viewModel.ValidateIdCommand.Execute(viewModel.Id);
So far so good.到目前为止,一切都很好。
As commented by @KlausGütter, you should mock the call to MessageBox.Show
to get this working.正如@KlausGütter 评论的那样,您应该模拟对
MessageBox.Show
的调用以使其正常工作。
A common and easy approach is to create a dialog service that implements an interface:一种常见且简单的方法是创建一个实现接口的对话服务:
public interface IDialogService
{
void ShowError(string text, string caption);
}
public class DialogService : IDialogService
{
public void ShowError(string text, string caption) =>
MessageBox.Show(text, caption, MessageBoxButton.OK, MessageBoxImage.Error);
}
...and inject the view model with the interface: ...并使用接口注入视图 model:
private readonly IDialogService _dialogService;
public ViewModel(string initials, IDialogService dialogService)
{
Initials = initials;
_dialogService = dialogService ?? throw new ArgumentNullException(nameof(dialogService));
}
private void ValidateId(string Id) // potentailly this should return a bool on successful/unsuccessful validation to make testing easier.
{
if (Id != null)
{
if (IdValidator.IsValidId(Id))
{
switch (IdValidator.ValidateId(AliquotId))
{
case IdType.Sample:
GetSample(Id);
break;
default:
break;
}
}
else
{
_dialogService.Show("Scanned Code not recognised", "Error");
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.