如何模拟持有 CrossFilePicker 的异步方法?
How can I Mock async method holding CrossFilePicker?
我正在研究 Xamarin.Forms 项目,即使用 Autofac
、Moq
和 Plugin.FilePicker
。
其中一个按钮命令是调用方法:
private async void OnLoadFileExecute(object obj)
{
await PickUpFile();
LoadedPhrases = LoadFromFile(FileLocation);
PopulateDb(LoadedPhrases);
LoadGroups();
}
而PickUpFile()
方法是async
:
public async Task<string> PickUpFile()
{
try
{
FileLocation = "";
var file = await CrossFilePicker.Current.PickFile();
if (file != null)
{
FileLocation = file.FilePath;
return FileLocation;
}
else
{
FileLocation = "";
return "";
}
}
catch (Exception ex)
{
Debug.WriteLine("Exception choosing file: " + ex.ToString());
return "";
}
}
我想测试整个命令,所以 OnLoadFileExecute
中的所有方法都将被测试。在那种情况下,我不确定如何将 PickUpFile()
方法设置为 return 一些 string
。据我所知,我不能在 interface
中使用异步方法。如果我错了,请纠正我。如果可以,我就可以嘲笑它。
您可以在界面中使用Task
。当你模拟它时,你需要 return Task.FromResult
在我看来,它应该是这样的
public interface IFileService {
Task<string> PickUpFile();
}
public class FileService : IFileService {
public async Task<string> PickUpFile() {
// here you have your implementation
}
}
// Here is the test method
public async Task TestTheService() {
const string fileName = "filename.txt";
var fileMocker = new Mock<IFileService>();
fileMocker.Setup( x => x.PickUpFile() ).Returns( Task.FromResult( fileName ) );
var mainClass = new MainClass( fileMocker.Object );
await mainClass.OnLoadFileExecute( null );
Assert.Equal( fileName, mainClass.FileLocation );
}
// here is the real class
public class MainClass {
private IFileService FileService { get; }
public string FileLocation { get; set; }
public MainClass( IFileService fileService ) {
FileService = fileService;
}
private async Task OnLoadFileExecute( object obj )
{
FileLocation = await FileService.PickUpFile();
LoadedPhrases = LoadFromFile( FileLocation );
PopulateDb( LoadedPhrases );
LoadGroups();
}
}
我正在研究 Xamarin.Forms 项目,即使用 Autofac
、Moq
和 Plugin.FilePicker
。
其中一个按钮命令是调用方法:
private async void OnLoadFileExecute(object obj)
{
await PickUpFile();
LoadedPhrases = LoadFromFile(FileLocation);
PopulateDb(LoadedPhrases);
LoadGroups();
}
而PickUpFile()
方法是async
:
public async Task<string> PickUpFile()
{
try
{
FileLocation = "";
var file = await CrossFilePicker.Current.PickFile();
if (file != null)
{
FileLocation = file.FilePath;
return FileLocation;
}
else
{
FileLocation = "";
return "";
}
}
catch (Exception ex)
{
Debug.WriteLine("Exception choosing file: " + ex.ToString());
return "";
}
}
我想测试整个命令,所以 OnLoadFileExecute
中的所有方法都将被测试。在那种情况下,我不确定如何将 PickUpFile()
方法设置为 return 一些 string
。据我所知,我不能在 interface
中使用异步方法。如果我错了,请纠正我。如果可以,我就可以嘲笑它。
您可以在界面中使用Task
。当你模拟它时,你需要 return Task.FromResult
在我看来,它应该是这样的
public interface IFileService {
Task<string> PickUpFile();
}
public class FileService : IFileService {
public async Task<string> PickUpFile() {
// here you have your implementation
}
}
// Here is the test method
public async Task TestTheService() {
const string fileName = "filename.txt";
var fileMocker = new Mock<IFileService>();
fileMocker.Setup( x => x.PickUpFile() ).Returns( Task.FromResult( fileName ) );
var mainClass = new MainClass( fileMocker.Object );
await mainClass.OnLoadFileExecute( null );
Assert.Equal( fileName, mainClass.FileLocation );
}
// here is the real class
public class MainClass {
private IFileService FileService { get; }
public string FileLocation { get; set; }
public MainClass( IFileService fileService ) {
FileService = fileService;
}
private async Task OnLoadFileExecute( object obj )
{
FileLocation = await FileService.PickUpFile();
LoadedPhrases = LoadFromFile( FileLocation );
PopulateDb( LoadedPhrases );
LoadGroups();
}
}