Search code examples
c#nunitmoqazure-cognitive-search

Unsupported expression when trying to mock the number of Fields on Azure Search Model


I am trying to unit test the following method:

 public bool CompareIndexEquality(Index resultBody, Type indexType)
        {
            var properties = indexType.GetProperties(BindingFlags.Instance | BindingFlags.Public);
            if (properties.Count() == resultBody.Fields.Count)
            {
                HavePropertyAttributesChanged(properties);
            }
            return false;
        }

My attempt is this:

[Test]
        public void CompareIndexEquality_AnyCase_ReturnsTrueIfAttributesMatch()
        {
            var compareSearchIndexService = new CompareSearchIndexService();
            var indexTypeMock =  new Mock<Type>();
            var resultBodyMock = new Mock<Microsoft.Azure.Search.Models.Index>();
            var lookUpIndexModel = new LookUpIndexModel();
            PropertyInfo[] propertyInfo = lookUpIndexModel.GetType().GetProperties();


            indexTypeMock.Setup(r => r.GetProperties(BindingFlags.Instance | BindingFlags.Instance)).Returns(propertyInfo);
            resultBodyMock.Setup(r => r.Fields).Returns(new List<Field>());
            var result = compareSearchIndexService.CompareIndexEquality(resultBodyMock.Object, indexTypeMock.Object);
            Assert.IsFalse(result);
        }

I receive the error: $exception {"Unsupported expression: r => r.Fields\nNon-overridable members (here: Index.get_Fields) may not be used in setup / verification expressions."} System.NotSupportedException

Does anyone know how I can mock the fields on an Microsoft.Azure.Search.Models.Index ?

Thank you


Solution

  • Moq creates an implementation of the mocked type. If the type is a class, it creates an inherited class, and the members of that inherited class call the base class. But in order to do that it has to override the members. If a class has members that can't be overridden (they aren't virtual, abstract) then Moq can't override them to add its own behaviors.

    How do we determine whether or not to mock something?

    Generally speaking, we mock something if we don't want to include the concrete runtime implementation in our test. We want to test one class not both at the same time.

    But in this case CompareIndexEquality is just a class that judges data. There's really no point in mocking it. It's just as easy to use the real thing.