I've read and test all these answers (this, this and this) but didn't help (also it's not my first use of mocking in such a situation, but this case is rare for me).
I'm using moq
and xunit
for my unit testing purpose. In testing ViewModel
I mocked service
and page
and passed them to it, everything is working but not page.CountDialog
that returns null, this is my code:
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
}
}