I'm attempting to create a test which verifies that a specific method is called. The method accepts two parameters, and I'd like to check that it gets called with that object having a specific property set.
Here's the code:
private void InitialiseContentTypes()
{
IContentType blogContentTypeComposition = _blogContentTypeFactory.GetComposition();
_umbracoContentTypeService.Save(blogContentTypeComposition);
}
This gets the composition from a factory, then uses it in the Save
method. In the test, the blogContentTypeComposition
should have a property called alias set to aldusBlogComposition
(blogContentTypeComposition.Alias
).
Here's the test code:
[Test]
[TestCase("aldusBlogComposition")]
public void Initialise_WhenCalled_SavesComposition(string alias)
{
Mock<IContentType> contentType = new Mock<IContentType>();
_blogContentTypeFactory
.Setup(f => f.GetComposition())
.Callback(() => { contentType.SetupProperty(ct => ct.Alias, alias); });
_component.Initialize();
_contentTypeService.Verify(s => s.Save(It.Is<IContentType>(ct => ct.Alias == alias), It.IsAny<int>()), Times.Once);
}
This code creates a mock IContentType and when GetComposition
is called, it sets the alias to aldusBlogComposition
. Then the Verify
should check that the Save
method runs once, with the first parameter an IContentType with the alias property set to aldusBlogComposition
.
When I run the test, this throws an error (below) which I suspect means that the mock isn't being used in the Verify method call.
Object reference not set to an instance of an object.
What am I missing?
EDIT:
The error is being thrown as part of the contentTypeService.Verify(s => s.Save(It.Is<IContentType>(ct => ct.Alias == alias), It.IsAny<int>()), Times.Once);
call. The only thing I can see being null
is ct
- if I swap this out for just It.IsAny<IContentType>()
the error isn't thrown. I understand what a null reference is, but I don't understand why the parameter is null.
Full classes for reference:
Tests class:
using Moq;
using NUnit.Framework;
using Papermoon.Umbraco.Aldus.Core.Components;
using Papermoon.Umbraco.Aldus.Core.Factories.ContentTypes.Interfaces;
using Papermoon.Umbraco.Aldus.Core.Services.Interfaces;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
namespace Papermoon.Umbraco.Aldus.Core.Tests.Components
{
[TestFixture]
public class ContentTypeComponentTests
{
private Mock<IContentTypeService> _contentTypeService;
private Mock<IAldusContentTypeContainerService> _contentTypeContainerService;
private Mock<IBlogContentTypeFactory> _blogContentTypeFactory;
private ContentTypeComponent _component;
[SetUp]
public void SetUp()
{
_contentTypeService = new Mock<IContentTypeService>();
_contentTypeContainerService = new Mock<IAldusContentTypeContainerService>();
_blogContentTypeFactory = new Mock<IBlogContentTypeFactory>();
_component = new ContentTypeComponent(_contentTypeService.Object, _contentTypeContainerService.Object, _blogContentTypeFactory.Object);
}
[Test]
public void Initialize_WhenCalled_GetAldusContainer()
{
_component.Initialize();
_contentTypeContainerService.Verify(s => s.GetContainer("Aldus", 1, -1));
}
[Test]
public void Initialise_AldusContainerExists_GetAldusCompositionContainer()
{
_contentTypeContainerService
.Setup(s => s.GetContainer("Aldus", 1, -1))
.Returns(new EntityContainer(Constants.ObjectTypes.DocumentType)
{
Id = 1
});
_component.Initialize();
_contentTypeContainerService.Verify(s => s.GetContainer("Aldus Compositions", 2, 1));
}
[Test]
public void Initialise_AldusContainerDoesNotExist_DoNoGetAldusCompositionsContainer()
{
_contentTypeContainerService
.Setup(s => s.GetContainer("Aldus", 1, -1))
.Returns((EntityContainer) null);
_component.Initialize();
_contentTypeContainerService.Verify(s => s.GetContainer("Aldus Compositions", 2, It.IsAny<int>()), Times.Never());
}
[Test]
[TestCase("aldusBlogComposition")]
public void Initialise_WhenCalled_SavesComposition(string alias)
{
Mock<IContentType> contentType = new Mock<IContentType>();
_blogContentTypeFactory
.Setup(f => f.GetComposition())
.Callback(() => { contentType.SetupProperty(ct => ct.Alias, alias); });
_component.Initialize();
_contentTypeService.Verify(s => s.Save(It.IsAny<IContentType>(), It.IsAny<int>()), Times.Once);
}
[Test]
public void Initialise_WhenCalled_SavesBlogContentType()
{
Mock<IContentType> contentType = new Mock<IContentType>();
contentType.SetupProperty(ct => ct.Alias, "aldus");
_blogContentTypeFactory
.Setup(f => f.GetContentType())
.Returns(contentType.Object);
_component.Initialize();
_contentTypeService.Verify(s => s.Save(contentType.Object, It.IsAny<int>()), Times.Once);
}
}
}
Component class:
using Papermoon.Umbraco.Aldus.Core.Factories.ContentTypes.Interfaces;
using Papermoon.Umbraco.Aldus.Core.Services.Interfaces;
using Umbraco.Core.Composing;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
namespace Papermoon.Umbraco.Aldus.Core.Components
{
public class ContentTypeComponent : IComponent
{
private readonly IAldusContentTypeContainerService _contentTypeContainerService;
private readonly IContentTypeService _umbracoContentTypeService;
private EntityContainer _aldusContainer;
private readonly IBlogContentTypeFactory _blogContentTypeFactory;
public ContentTypeComponent(
IContentTypeService umbracoContentTypeService,
IAldusContentTypeContainerService contentTypeContainerService,
IBlogContentTypeFactory blogContentTypeFactory)
{
_umbracoContentTypeService = umbracoContentTypeService;
_contentTypeContainerService = contentTypeContainerService;
_blogContentTypeFactory = blogContentTypeFactory;
}
public void Initialize()
{
InitialiseContainers();
InitialiseContentTypes();
}
private void InitialiseContainers()
{
_aldusContainer = _contentTypeContainerService.GetContainer("Aldus", 1);
if (_aldusContainer != null)
{
_contentTypeContainerService.GetContainer("Aldus Compositions", 2, _aldusContainer.Id);
}
}
private void InitialiseContentTypes()
{
IContentType blogContentTypeComposition = _blogContentTypeFactory.GetComposition();
_umbracoContentTypeService.Save(blogContentTypeComposition);
IContentType blogContentType = _blogContentTypeFactory.GetContentType();
_umbracoContentTypeService.Save(blogContentType);
}
public void Terminate() { }
}
}
And the blog factory class:
using System.Collections.Generic;
using System.Linq;
using Papermoon.Umbraco.Aldus.Core.Factories.ContentTypes.Interfaces;
using Papermoon.Umbraco.Utils.Services.Interfaces;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
namespace Papermoon.Umbraco.Aldus.Core.Factories.ContentTypes
{
public class BlogContentTypeFactory : ContentTypeFactory, IBlogContentTypeFactory
{
public BlogContentTypeFactory(
IContentTypeService contentTypeService,
IPapermoonContentTypeService papermoonContentTypeService,
IPapermoonContentTypeContainerService papermoonContentTypeContainerService,
IPapermoonTemplateService papermoonTemplateService)
: base(
contentTypeService,
papermoonContentTypeService,
papermoonContentTypeContainerService,
papermoonTemplateService) { }
public IContentType GetComposition()
{
Composition = ContentTypeService.Get("aldusBlogComposition");
if (Composition == null)
{
Composition = new ContentType(AldusCompositionsContainer.Id);
}
Composition.Name = "Aldus Blog Composition";
Composition.Alias = "aldusBlogComposition";
Composition.Description = "A composition for the Aldus blog listing.";
Composition.Icon = "icon-settings";
return Composition;
}
public IContentType GetContentType()
{
ContentType = ContentTypeService.Get("aldusBlog");
if (ContentType == null)
{
ContentType = new ContentType(AldusContainer.Id);
}
ContentType.Name = "Blog";
ContentType.Alias = "aldusBlog";
ContentType.Description = "Aldus blog listing.";
ContentType.Icon = "icon-article";
ContentType.AllowedTemplates = PapermoonTemplateService.Get(new [] { "AldusBlog" });
ContentType.SetDefaultTemplate(ContentType.AllowedTemplates.First());
ContentType.ContentTypeComposition =
PapermoonContentTypeService.GetCompositions(ContentType, new List<string> {"aldusBlogComposition"});
return ContentType;
}
}
}
And finally, the content type factory class:
using System.Collections.Generic;
using System.Linq;
using Papermoon.Umbraco.Aldus.Core.Factories.ContentTypes.Interfaces;
using Papermoon.Umbraco.Utils.Services.Interfaces;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
namespace Papermoon.Umbraco.Aldus.Core.Factories.ContentTypes
{
public class BlogContentTypeFactory : ContentTypeFactory, IBlogContentTypeFactory
{
public BlogContentTypeFactory(
IContentTypeService contentTypeService,
IPapermoonContentTypeService papermoonContentTypeService,
IPapermoonContentTypeContainerService papermoonContentTypeContainerService,
IPapermoonTemplateService papermoonTemplateService)
: base(
contentTypeService,
papermoonContentTypeService,
papermoonContentTypeContainerService,
papermoonTemplateService) { }
public IContentType GetComposition()
{
Composition = ContentTypeService.Get("aldusBlogComposition");
if (Composition == null)
{
Composition = new ContentType(AldusCompositionsContainer.Id);
}
Composition.Name = "Aldus Blog Composition";
Composition.Alias = "aldusBlogComposition";
Composition.Description = "A composition for the Aldus blog listing.";
Composition.Icon = "icon-settings";
return Composition;
}
public IContentType GetContentType()
{
ContentType = ContentTypeService.Get("aldusBlog");
if (ContentType == null)
{
ContentType = new ContentType(AldusContainer.Id);
}
ContentType.Name = "Blog";
ContentType.Alias = "aldusBlog";
ContentType.Description = "Aldus blog listing.";
ContentType.Icon = "icon-article";
ContentType.AllowedTemplates = PapermoonTemplateService.Get(new [] { "AldusBlog" });
ContentType.SetDefaultTemplate(ContentType.AllowedTemplates.First());
ContentType.ContentTypeComposition =
PapermoonContentTypeService.GetCompositions(ContentType, new List<string> {"aldusBlogComposition"});
return ContentType;
}
}
}
Furthermore, I've tried adding a call to .Returns
but still see the error. I've tried the following ways:
After the callback:
_blogContentTypeFactory
.Setup(f => f.GetComposition())
.Callback(() => { contentType.SetupProperty(ct => ct.Alias == alias); })
.Returns(contentType.Object);
Assignment as part of the return:
_blogContentTypeFactory
.Setup(f => f.GetComposition())
.Returns(contentType.SetupProperty(ct => ct.Alias, alias).Object);