Unit Testing for Page navigation from viewmodel is not working

hi all
I want write unit test for navigate to Mastedetail Page from my LoginViewModel
My case is:
Application.Current.MainPage.Navigation.PushModalAsync(new MainPage());
here my MainPage is Masterdetai Page and here if write Unit Test case like this

    [Test]
    public async Task Test1()
    {
        var lvm = new LoginViewModel();
        lvm.Username = "admin";
        lvm.Password = "admin";
        var app = new App();

        var page = new ContentPage();

        Application.Current.MainPage = new MainPage();
        await Application.Current.MainPage.Navigation.PushModalAsync(page1);
        string result = lvm.LoginResult();
        Assert.IsTrue(result == "Success", "test fail");
        Assert.Pass();
    }

its giving System.InvalidOperationException: You MUST call Xamarin.Forms.Init(); prior to using it, error at master detail page line MasterBehavior = MasterBehavior.Popover;

if any one have idea please let me know how to get Application.current.mainpage in unit test project and how to resolve this issue
Thanks In Advance

Posts

  • JohnHJohnH GBMember ✭✭✭✭✭

    I would advise against unit testing the Xamarin Forms navigation code.
    Also, your LoginViewModel doesn't appear to be using Xamarin Forms at all (and it shouldn't), so the creation of a main page, content page etc is irrelevant to the test. The test appears to be just testing the LoginResult() method.

  • divyagarimelladivyagarimella Member ✭✭

    Hi @JohnH
    Thanks for your reply
    i am using mvvm pattern so my navigation would be in my loginviewmodel page and my loginviewmodel class looks like this
    public string LoginResult()
    {

            try
            {
                string[] admindetails = new string[] { "admin", "admin" };
                if (!string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password))
                {
                    if (admindetails[0] == username && admindetails[1] == password)
                    {
                        Application.Current.Properties["AdminUserName"] = username;
                        Task.Run(async () => await Application.Current.SavePropertiesAsync());
                        Application.Current.Properties["AdminPassword"] = username;
                        Task.Run(async () => await Application.Current.SavePropertiesAsync());
                        Application.Current.MainPage.Navigation.PushModalAsync(new MainPage());
                        return "Success";
                    }
                    else
                    {
                        //if login not successfull displaying alert 
                        Application.Current.MainPage.DisplayAlert("Error", "InCorrect UserName or Password", "OK");
                        UserDialogs.Instance.HideLoading();
                        return "fail";
                    }
                }
    
                else
                {
                    Application.Current.MainPage.DisplayAlert("Error", "Username or password Cannot be empty", "OK");
                    UserDialogs.Instance.HideLoading();
                    return "fail";
                }
    
    
            }
            catch (Exception ex)
            {
    
                Application.Current.MainPage.DisplayAlert("Error", "Login Failed...", "OK");
                UserDialogs.Instance.HideLoading();
                Application.Current.Properties.Clear();
                return ex.Message;
            }
    
        }
    
  • JohnHJohnH GBMember ✭✭✭✭✭

    I would seriously suggest you look at the SOLID principles. Your view model should not be calling Xamarin specific methods at all, they should be abstractions that you can then mock in your unit tests.
    That way your unit tests can run without needing Xamarin at all, you are then testing the logic in your view models cleanly.

Sign In or Register to comment.