Copied to clipboard

Flag this post as spam?

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


  • nickornotto 317 posts 679 karma points
    Jun 11, 2018 @ 10:47
    nickornotto
    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 129 posts 618 karma points
    Jun 12, 2018 @ 08:12
    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);
    
  • nickornotto 317 posts 679 karma points
    Jun 12, 2018 @ 10:34
    nickornotto
    0

    I'm getting error as well:

    System.NotSupportedException: 'Invalid setup on an extension method: c => c.HasProperty("test")'
    
  • Alex Brown 129 posts 618 karma points
    Jun 12, 2018 @ 13:30
    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).

  • nickornotto 317 posts 679 karma points
    Jun 13, 2018 @ 11:08
    nickornotto
    0

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

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies