简体   繁体   中英

How can I Mock async method holding CrossFilePicker?

I am working on Xamarin.Forms project, that is using Autofac , Moq , and Plugin.FilePicker .

One of button commands is calling method:

private async void OnLoadFileExecute(object obj)
{
    await PickUpFile();
    LoadedPhrases = LoadFromFile(FileLocation);
    PopulateDb(LoadedPhrases);
    LoadGroups();
}

And PickUpFile() method is 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 "";
    }
}

I wanted to test whole command, so all methods in OnLoadFileExecute will be tested. In that case I am not sure how can I Setup PickUpFile() method to return some string . As far as I know, I can not use in the interface async methods. Correct me if I am wrong. If I could, I would be able to mock it.

You can use Task in the interface. When you mock it, you will need to return Task.FromResult

From my point of view, it should look like this

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();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM