模拟异步任务方法使用C#和Xamarin返回null

时间:2017-09-07 06:26:27

标签: c# unit-testing xamarin

我已经阅读并测试了所有这些答案(thisthisthis),但没有帮助(也不是我的第一个答案)在这种情况下使用嘲弄,但这种情况对我来说很少见。)

我使用moqxunit进行单元测试。在测试ViewModel时,我模拟servicepage并将它们传递给它,一切正常但不是page.CountDialog返回null,这是我的代码:

Page.cs:

public interface IPage
{
    Task<PromptResult> CountDialog(decimal previousCount);
}

PageViewModel:

public class PageViewModel : ViewModelBase<ObservableRangeCollection<Detail>>
{
    private readonly IPage _page;
    private readonly IService _service;
    private ICommand _editItemCommand;

    public PageViewModel(IService service, IPage page)
    {
        _service = service;
        _page = page;
        Data = new ObservableRangeCollection<Detail>();
    }

    public ICommand EditItemCommand
    {
        get => _editItemCommand ??
               (_editItemCommand = new Command<Detail>(async (o) => { await EditItem(o); }));
        set => _editItemCommand = value;
    }

    public async Task EditItem(Detail detail)
    {
        if (detail == null) return;
        try
        {
            var result = await _page.CountDialog(detail.Count); // It should return PromptResult (from UserDialogs lib) but every time is null, in normal running app, it works and is Not null
            if (result == null) return; //in test is usually null
            if (!result.Ok || string.IsNullOrWhiteSpace(result.Text)) return;
            var newCount = Convert.ToInt32(result.Text);
            var res = await _service.EditItem(detail, newCount);
            if (res.Status)
                UpdatePageItem(detail, newCount);
        }
        catch (RestException exception)
        {
           // nothing
        }
    }
 }

ViewModelTest.cs:

public class ViewModelTest
{
    Mock<IService> _service = new Mock<IService>();
    Mock<IPage> _page = new Mock<IPage>();
    private PageViewModel _viewModel;

    public PageViewModelTest()
    {
        _viewModel = new PageViewModel(_service.Object, _page.Object);
    }

    [Fact]
    public async Task EditItemTest_SuccessAsync()
    {
        var pageItems = GetItemsFake();
        var result = new PromptResult(true, "12"); // the result i wish to be returned (but is usually null)
        _page.Setup(x => x.CountDialog(It.IsAny<int>())).ReturnsAsync(result); // this is mock part that not work
        _service.Setup(x => x.GetItems(It.IsAny<int>())).ReturnsAsync(pageItems);// works 
        _service.Setup(c => c.EditItem(It.IsAny<int>(), It.IsAny<Detail>(), It.IsAny<int>())).ReturnsAsync(
            new ActionResponse
            {
                Result = "OK"
            });//works

        _viewModel.LoadDataCommand.Execute(true);
        await _viewModel.EditItem(pageItems .ElementAt(0)); // after this line code goes to _viewModel class and there is null
        //            _viewModel.EditItemCommand.Execute(pageItems.ElementAt(0)); // Also checked this one too, but not work too

        Assert.Equal(12, _viewModel.Data.ElementAt(0).Count); // not passed due to not working mock
    }
}

1 个答案:

答案 0 :(得分:2)

那是因为CountDialog需要decimal而不是int

试试这个:

_page.Setup(x => x.CountDialog(It.IsAny<decimal>())).ReturnsAsync(result);