umbraco / UmbracoDocs

The official Umbraco Documentation
https://docs.umbraco.com
MIT License
266 stars 770 forks source link

Unit testing IPublishedContent Value extension method fallbacks #1663

Closed stevetemple closed 5 years ago

stevetemple commented 5 years ago

What type of issue is it? (Choose one - delete the others)

Missing documentation

What article/section is this about?

Following on from Twitter discussion: https://twitter.com/zpqrtbnk/status/1115297266036875265 about unit testing IPublishedContent in v8

Describe the issue:

What is the best way of mocking/faking IPublishedContent Value extension methods fallbacks?

In v7 as long as the IPublishedContent was setup correctly the extension methods would work as they were pretty self contained within the IPublishedContent. With v8 the fallbacks rely on some dependencies having been configured. Is there a way of mocking/faking these that doesn't require creating an entire umbraco instance?

For reference in some of the Umbraco-Ditto tests (https://github.com/umco/umbraco-ditto/blob/6ad7853f9502dbde4736d894f882debf11b67c45/tests/Our.Umbraco.Ditto.Tests/ValueTypesTests.cs#L39) for example we get

System.Exception : No container has been set.
   at Umbraco.Core.Composing.Current.get_Container()
   at Umbraco.Core.Composing.Current.get_PublishedValueFallback()
   at Umbraco.Web.Composing.Current.get_PublishedValueFallback() in C:\working.git\umbracov8\src\Umbraco.Web\Composing\Current.cs:line 251
   at Umbraco.Web.PublishedContentExtensions.get_PublishedValueFallback() in C:\working.git\umbracov8\src\Umbraco.Web\PublishedContentExtensions.cs:line 26
   at Umbraco.Web.PublishedContentExtensions.Value(IPublishedContent content, String alias, String culture, String segment, Fallback fallback, Object defaultValue) in C:\working.git\umbracov8\src\Umbraco.Web\PublishedContentExtensions.cs:line 207
   at Our.Umbraco.Ditto.UmbracoPropertyAttribute.GetUmbracoPropertyValue(IPublishedContent content, String umbracoPropertyName, Boolean recursive) in C:\working.git\umbraco-ditto\src\Our.Umbraco.Ditto\ComponentModel\Processors\UmbracoPropertyAttribute.cs:line 228
   at Our.Umbraco.Ditto.UmbracoPropertyAttribute.GetPropertyValue(IPublishedContent content, String umbracoPropertyName, Boolean recursive) in C:\working.git\umbraco-ditto\src\Our.Umbraco.Ditto\ComponentModel\Processors\UmbracoPropertyAttribute.cs:line 170
   at Our.Umbraco.Ditto.UmbracoPropertyAttribute.ProcessValue() in C:\working.git\umbraco-ditto\src\Our.Umbraco.Ditto\ComponentModel\Processors\UmbracoPropertyAttribute.cs:line 131
   at Our.Umbraco.Ditto.DittoCacheableAttribute.GetCacheItem[TOuputType](DittoCacheContext cacheContext, Func`1 refresher) in C:\working.git\umbraco-ditto\src\Our.Umbraco.Ditto\ComponentModel\Attributes\DittoCacheableAttribute.cs:line 62
   at Our.Umbraco.Ditto.DittoProcessorAttribute.ProcessValue(Object value, DittoProcessorContext context, DittoChainContext chainContext) in C:\working.git\umbraco-ditto\src\Our.Umbraco.Ditto\ComponentModel\Attributes\DittoProcessorAttribute.cs:line 187
   at Our.Umbraco.Ditto.PublishedContentExtensions.DoGetProcessedValue(IPublishedContent content, DittoTypePropertyInfo mappableProperty, DittoProcessorContext baseProcessorContext, DittoChainContext chainContext) in C:\working.git\umbraco-ditto\src\Our.Umbraco.Ditto\Extensions\PublishedContentExtensions.cs:line 314
   at Our.Umbraco.Ditto.PublishedContentExtensions.GetProcessedValue(IPublishedContent content, CultureInfo culture, DittoTypeInfo config, DittoTypePropertyInfo mappableProperty, Object instance, DittoChainContext chainContext) in C:\working.git\umbraco-ditto\src\Our.Umbraco.Ditto\Extensions\PublishedContentExtensions.cs:line 282
   at Our.Umbraco.Ditto.PublishedContentExtensions.ConvertContent(IPublishedContent content, DittoTypeInfo config, CultureInfo culture, Object instance, Action`1 onConverting, Action`1 onConverted, DittoChainContext chainContext) in C:\working.git\umbraco-ditto\src\Our.Umbraco.Ditto\Extensions\PublishedContentExtensions.cs:line 233
   at Our.Umbraco.Ditto.PublishedContentExtensions.As(IPublishedContent content, Type type, CultureInfo culture, Object instance, IEnumerable`1 processorContexts, Action`1 onConverting, Action`1 onConverted, DittoChainContext chainContext) in C:\working.git\umbraco-ditto\src\Our.Umbraco.Ditto\Extensions\PublishedContentExtensions.cs:line 151
   at Our.Umbraco.Ditto.PublishedContentExtensions.As[T](IPublishedContent content, CultureInfo culture, T instance, IEnumerable`1 processorContexts, Action`1 onConverting, Action`1 onConverted, DittoChainContext chainContext) in C:\working.git\umbraco-ditto\src\Our.Umbraco.Ditto\Extensions\PublishedContentExtensions.cs:line 41
   at Our.Umbraco.Ditto.Tests.ValueTypesTests.ValueTypes_With_DefaultValue() in C:\working.git\umbraco-ditto\tests\Our.Umbraco.Ditto.Tests\ValueTypesTests.cs:line 43
jmayntzhusen commented 5 years ago

Hey @stevetemple

Thanks for bringing it here so we can hopefully get it documented for v8!

zpqrtbnk commented 5 years ago

Quick note: extension methods, being static, have no choice but to use the Current service locator to resolve their dependencies - here, the IPublishedValueFallback - which means that setting up a very minimal container is unfortunately required.

The simplest way to do so is:

var factory = Mock.Of<IFactory>();
Mock.Get(factory)
    .Setup(x => x.GetInstance(typeof(IPublishedValueFallback)))
    .Returns(...);
Current.Factory = container.Object;
stevetemple commented 5 years ago

Thanks @zpqrtbnk, this is really helpful to know, I'll get some docs together to reflect this once I've tried it out

jmayntzhusen commented 5 years ago

Hey @stevetemple

We now have a page on unit testing in v8, feel free to add any additional findings to it: https://our.umbraco.com/documentation/Implementation/Unit-Testing/

nul800sebastiaan commented 5 years ago

This issue has been in the up for grabs state for quite a while now and it seems nobody is ready to pick this one up.

For now we'll close this issue to prevent the list of up for grabs from becoming very stale. We're happy to re-open it if someone still thinks it's good to work on this.

If anyone is about to pick this issue up to fix it, make sure to test first if you can reproduce the problem in the latest version before you start to work on it.

Thanks! Sebastiaan on behalf of Umbraco HQ.