Copied to clipboard

Flag this post as spam?

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


  • John 79 posts 115 karma points
    Apr 11, 2014 @ 10:41
    John
    0

    Unit Testing IPublishedContent when using GetPropertyValue

    We have a number of classes that use INode, and we are just in the process of converting them to IPublishedContent.  As part of this, we are updating our unit tests accordingly.

    We use Moq to create a mocked up IPublishedContent, and add a mocked IPublishedContentProperty to its properties collection.

    The coed we are testing retrieves a property value from IPublishedContent using GetPropertyValue.

    I was expecting this to return the value of the IPublishedContentProperty, but wrapepd in a null check.  However, it seems to call out to "PublishedContentHelper.GetDataType" to get the GUID of the data type for the property.  In turn, this calls out to applicationContext.Services.ContentTypeService, and at this point through a null reference exception because there is no application context.

    I believe there is an Umbraco project designed to help with unit testing.  I am a little loathe to have to create a dummy application context and wire it up because this means my unit tests are going to have to be very aware of the Umbraco internals and I think this is going to make them hard to read and potentially a bit fragile.  Whereas with using an interface it feels like this shouldn't be necessary.

    Is there an easy way to do this?  I realise we could just change our code so that it doesn't use the GetPropertyValue extension method but it feels like we are reinventing the wheel.

    And out of curiosity, why does it need to do this when the property does include a value?  (So if we did decide to write our own - what would we be missing?)

    Thanks!

    John

  • Dennis Spijkerboer 53 posts 95 karma points
    Jul 29, 2014 @ 16:55
    Dennis Spijkerboer
    0

    Good question, just ran into the same problem. Have you found a (nice) workaround for this?

  • John 79 posts 115 karma points
    Jul 30, 2014 @ 11:44
    John
    0

    Not really, I'm afraid, I just gave up.  :(

    I was trying to convert something from using the old INode interface to IPublishedContent.  After I battled with this for a bit I decided not to bother, so just left the code as INode.

    The only other ways I can think of are looking at the test version of the application context or not using GetPropertyValue.  I did wonder if a GetPropertyValueWithoutHittingDatabase<T> extension of my own might work.  Presumably the DB hit is needed for something though.  (?)

    I guess it might be possible to use something like MS Fakes if your Visual Studio license covers yo ufor it.  I think it allows you to mock up things that otherwise can't be mocked up, but I've not tried it.

    It's a real shame - as it's so close to being good.

  • Andy Butland 422 posts 2334 karma points MVP 4x hq c-trib
    Aug 01, 2014 @ 17:18
    Andy Butland
    0

    MS Fakes with the option I used for this.  As John notes you need VS.Net Premium or higher unfortunately.  I wrote up some notes on doing this here:

    Andy

  • Dennis Spijkerboer 53 posts 95 karma points
    Aug 04, 2014 @ 14:30
    Dennis Spijkerboer
    0

    Andy, thanks for the info! I will look into MS Fakes. No luck with mocks from Moq so far. I was able to mock IPublishedContent but you can't mock extension methods, so GetPropertyValue was giving me a hard time.

  • Michaela Ivanova 12 posts 104 karma points
    Aug 29, 2017 @ 09:53
    Michaela Ivanova
    1

    Hey,

    Instead of using GetPropertyValue

     var property = node.GetProperty("property");
                    if (property.HasValue)
                    {
                        var myInt = Convert.ToInt32(propertyValue);
                    }
    

    In your Unit Test:

    //Arrange
            var intProperty = new Mock<IPublishedProperty>();
            intProperty.SetupGet(p => p.HasValue).Returns(true);
            intProperty.Setup(p => p.Value).Returns(1024);
            intProperty.Setup(y => y.Value).Returns(intProperty.Object.Value);
    
            var node = new Mock<IPublishedContent>();
           node.Setup(y => y.GetProperty("something")).Returns(intProperty.Object);
    
            contentQ.Setup(x => x.TypedContentSingleAtXPath("//NodeDocType")).Returns(node.Object);
    
            //Act
            var actualNode =myclass.MyMethod();
    
            //Assert
            actualNode .Verify(p => p.GetProperty(It.IsAny<string>()), Times.AtLeastOnce);//make sure that the value Has Value check is performed
            intProperty.Verify(p => p.Value, Times.AtLeastOnce);//make sure that the value is assigned
    

    Hope this will help :)

Please Sign in or register to post replies

Write your reply to:

Draft