Search code examples
unit-testingmoqviewmodel

Non-overridable members may not be used in setup / verification expressions


I'm trying to do some unittesting on a method that is in a FreshMVVM view model (so no interface). I want to parse two properties with values as well.

I think I found the way to parse the properties. But I get the following exception while running the tests : Non-overridable members (here: Search ViewModel.ExecuteSearch Command) may not be used in setup / verification expressions.

The method is set public and so are the properties. I can not change them to virtual because then I get an error in my method.

here is my code:

Viewmodel:

 public async void ExecuteSearchCommand()
        {
            ProductionOrders.Clear();
            ObservableCollection<ProductionOrder> allProductionorders = await GetDetailedProductionOrders();

            if (SelectedSearch == null || Input== null) {
                await Application.Current.MainPage.DisplayAlert("woeps", "please make your selection", "OK");
            }
            else
            {

                if (SelectedSearch == "Material")
                {
                    foreach (var productionOrder in allProductionorders)
                    {
                        if (productionOrder.MaterialNumber == Input)
                        {
                            ProductionOrders.Add(productionOrder);
                        }
                    }
                }
                else
                {
                    foreach (var productionOrder in allProductionorders)
                    {
                        if (productionOrder.OrderNumber == int.Parse(Input))
                        {
                            ProductionOrders.Add(productionOrder);
                        }
                    }
                }
                if (productionOrders.Count == 0)
                {
                    await Application.Current.MainPage.DisplayAlert("woeps", "No data found for this selection", "OK");
                }
            }

unit test:

 [Fact]
        public void ExecuteSearchCommand_WitCorrectData_ListProductionOrders()
        {
            //Arrange
            var testMaterial=testMaterials[0];
            var testProductionOrder = testProductionOrders[0];
        
            var mockVm = new Mock<SearchViewModel>();

            //act
            
            mockVm.Setup(vm => vm.ExecuteSearchCommand()).Equals(testProductionOrder);
            mockVm.SetupProperty(se => se.SelectedSearch,"Production Order") ;
            mockVm.SetupProperty(ip => ip.Input, "100001");

            Assert.NotNull(mockVm);
        }

I also tried this:

[Fact]
        public void ExecuteSearchCommand_WitCorrectData_ListProductionOrders()
        {
            //Arrange
            var testMaterial=testMaterials[0];
            var testProductionOrder = testProductionOrders[0];
         
           


            var mockVm = new SearchViewModel { SelectedSearch = "Production Order", Input="100001", ProductionOrders=new ObservableCollection<ProductionOrder>() };
            mockVm.ExecuteSearchCommand();

            //act
            
            

            Assert.NotNull(mockVm);
        }

But then I get an error in the GetDetailedProductionorders method used in the executesearchcommand()

I don't get this error when running the program (not the unit test) enter image description here

Could someone give me a hint in the right direction? Thx! Sarah


Solution

  • From the second unit test you tried, when you create instance of SearchViewModel, there is no initialize of _productionOrderService.

    if _productionOrderService is created in SearchViewModel it might not be initialized due to lack of their dependencies.

    you have to provide _productionOrderService to the SearchViewModel by

    1. make it public and set it when create SearchViewModel
    2. make it private and pass it through constructor when create SearchViewModel

    then you can mock _productionOrderService and setup GetListAllAsync() in unit test