我正在尝试创建一个测试,以验证是否调用了特定方法。该方法接受两个参数,我想检查是否已使用设置了特定属性的对象调用它。
代码如下:
private void InitialiseContentTypes()
{
IContentType blogContentTypeComposition = _blogContentTypeFactory.GetComposition();
_umbracoContentTypeService.Save(blogContentTypeComposition);
}
这将从工厂获取构图,然后在Save
方法中使用它。在测试中,blogContentTypeComposition
应该具有一个称为alias的属性,该属性设置为aldusBlogComposition
(blogContentTypeComposition.Alias
)。
这是测试代码:
[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);
}
此代码创建一个模拟IContentType,并在调用GetComposition
时将别名设置为aldusBlogComposition
。然后Verify
应该检查Save
方法是否运行一次,第一个参数是IContentType,别名属性设置为aldusBlogComposition
。
当我运行测试时,这会引发一个错误(如下),我怀疑这表明该模拟未在Verify方法调用中使用。
Object reference not set to an instance of an object.
我想念什么?
编辑:
该错误是作为contentTypeService.Verify(s => s.Save(It.Is<IContentType>(ct => ct.Alias == alias), It.IsAny<int>()), Times.Once);
调用的一部分引发的。我唯一能看到的是null
是ct
-如果仅将其交换为It.IsAny<IContentType>()
,就不会引发错误。我了解什么是空引用,但我不明白为什么参数为空。
完整类供参考:
测试类:
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);
}
}
}
组件类:
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() { }
}
}
以及博客工厂类:
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;
}
}
}
最后,内容类型为工厂类:
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;
}
}
}
此外,我尝试将通话添加到.Returns
,但仍然看到错误。我尝试了以下方法:
回调之后:
_blogContentTypeFactory
.Setup(f => f.GetComposition())
.Callback(() => { contentType.SetupProperty(ct => ct.Alias == alias); })
.Returns(contentType.Object);
分配作为回报的一部分:
_blogContentTypeFactory
.Setup(f => f.GetComposition())
.Returns(contentType.SetupProperty(ct => ct.Alias, alias).Object);
答案 0 :(得分:0)
是因为您错过了.Returns
工厂的Mock
用法吗?
contentType.SetupProperty(ct => ct.Alias, alias)
_blogContentTypeFactory
.Setup(f => f.GetComposition())
.Returns(contentType.SetupProperty);
很难说出具体类的实例周围没有更多的代码。
答案 1 :(得分:0)
有几种方法可以配置模拟及其属性。
以下内容使用LINQ to Mocks方法
[Test]
[TestCase("aldusBlogComposition")]
public void Initialise_WhenCalled_SavesComposition(string alias) {
//Arrange
IContentType contentType = Mock.Of<IContentType>(_ => _.ALias == alias);
_blogContentTypeFactory
.Setup(_ => _.GetComposition())
.Returns(contentType);
//Act
_component.Initialize();
//Assert
_contentTypeService.Verify(s => s.Save(It.Is<IContentType>(ct => ct.Alias == alias), It.IsAny<int>()), Times.Once);
}
您甚至可以验证它是否与传递的返回实例相同
//...omitted for brevity
//Assert
_contentTypeService.Verify(s => s.Save(contentType, It.IsAny<int>()), Times.Once);
//...
答案 2 :(得分:0)
结果证明Verify
的设置是正确的,但是从GetContentType
方法返回了一个空值,我只需要设置一个返回值:
_blogContentTypeFactory
.Setup(f => f.GetContentType())
.Returns(Mock.Of<IContentType>());