Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • manila 184 posts 406 karma points
    1 week ago
    manila
    0

    How to get HasProperty working when Unit testing umbraco IPublishedProperty?

    How to mock umbraco content and its properties so I could get the correct value of the property and HasProperty bool value?

    I'm trying to test such method:

            var properties = [...] // properties collection
            UmbProperties(properties, content, model);
    

    The method content:

        protected T UmbProperties(PropertyInfo[] properties, IPublishedContent content, T model)
        {
            foreach (PropertyInfo property in properties)
            {
                string umbracoPropertyName = Char.ToLowerInvariant(property.Name[0]) + property.Name.Substring(1);
                bool umbracoHasProperty = content.HasProperty(umbracoPropertyName); // this returns System.NullReferenceException when testing
    
                [...]
            }
    
            return model;
        }
    

    Currently in my test method I have:

        public void For_GetPropertyValueOfType()
        {
            var contentStub = new Mock<IPublishedContent>();
            var propertyStub = new Mock<IPublishedProperty>();
    
            propertyStub.Setup(p => p.Value).Returns("property value");
    
            contentStub.Setup(c => c.GetProperty("test", false)).Returns(propertyStub.Object);
    
            var model = [...] // some model
            var content = contentStub.Object;
    
            var properties = [...] // properties collection
            obj.UmbProperties(properties, content, model);
    
            [...]
        }
    

    content is set well and not null, but HasProperty returns an error:

    System.NullReferenceException: 'Object reference not set to an instance of an object.'
    

    How to get HasProperty working correctly when setting property in the test method?

    I don't want to do this for example:

    var propertyValue = content.GetPropertyValue<string>("test");
    var hasProp = propertyValue != null;
    

    because I'm checking for the property type later in UmbProperties.

    And this doesn't work either:

            var propertyValue = content.GetPropertyValue("test");
            var hasProp1 = propertyValue != null; // this returns false as propertyValue comes null if I;m not using type conversion as above
    
  • Alex Brown 106 posts 458 karma points
    1 week ago
    Alex Brown
    0

    Since you're calling HasProperty in your method, wouldn't you need to mock it?

    Something like

    contentStub.Setup(c => c.HasProperty("test").Returns(true);
    
  • manila 184 posts 406 karma points
    1 week ago
    manila
    0

    I'm getting error as well:

    System.NotSupportedException: 'Invalid setup on an extension method: c => c.HasProperty("test")'
    
  • Alex Brown 106 posts 458 karma points
    1 week ago
    Alex Brown
    0

    Right, I didn't realise HasProperty() was an extension method.

    You can't test extension methods, or do .Setup() on them.

    You'll have to create a wrapper for this method which can be a pain.

    If I were you I'd create an interface and class named "IPublishedContentWrapper" and then have a method called HasProperty. Then you can inject this interface into your method and call your new HasProperty method. You'll then have to mock it in your test. E.g.:

    public class PublishedContentWrapper : IPublishedContentWrapper 
    {
        public bool HasProperty(IPublishedContent node, string propertyName)
        {
             return node.HasProperty(propertyName);
        }
    }
    

    Then inject IPublishedContentWrapper as _publishedContent and change the UmbProperties method to call _publishedContent.HasProperty:

    bool umbracoHasProperty = _publishedContent.HasProperty(content, umbracoPropertyName); 
    

    Then change the setup method to add the following:

    var wrapperStub = new Mock<IPublishedContentWrapper>();
    wrapperStub.Setup(p => p.HasValue(propertyStub.Object, "test")).Returns(true);
    

    Hopefully this will work...

    Either way I know you can't mock extension methods and you typically create wrappers for them (as above).

  • manila 184 posts 406 karma points
    1 week ago
    manila
    0

    Hi, thanks! I'll try it and come back here.

Please Sign in or register to post replies

Write your reply to:

Draft