C# 单元测试Umbraco 8作曲家
我对单元测试还比较陌生,所以对我放松点!我试图使用一个相当简单的Umbraco 8项目作为一个测试平台。我目前一直在尝试测试一个注册了依赖项的编写器,并且很难弄清楚如何测试它 这段代码可能会很有说服力,因此无需进一步的麻烦,下面是我想要测试的作曲家。如您所见,它只是注册了一个针对接口编码的服务:C# 单元测试Umbraco 8作曲家,c#,unit-testing,dependency-injection,umbraco,umbraco8,C#,Unit Testing,Dependency Injection,Umbraco,Umbraco8,我对单元测试还比较陌生,所以对我放松点!我试图使用一个相当简单的Umbraco 8项目作为一个测试平台。我目前一直在尝试测试一个注册了依赖项的编写器,并且很难弄清楚如何测试它 这段代码可能会很有说服力,因此无需进一步的麻烦,下面是我想要测试的作曲家。如您所见,它只是注册了一个针对接口编码的服务: using Papermoon.Umbraco.Utils.Services; using Papermoon.Umbraco.Utils.Services.Interfaces; using Umbr
using Papermoon.Umbraco.Utils.Services;
using Papermoon.Umbraco.Utils.Services.Interfaces;
using Umbraco.Core;
using Umbraco.Core.Composing;
namespace Papermoon.Umbraco.Aldus.Core.Composers
{
[RuntimeLevel(MinLevel = RuntimeLevel.Run)]
public class ServicesComposer : IUserComposer
{
public void Compose(Composition composition)
{
composition.Register<IPapermoonContentTypeContainerService, PapermoonContentTypeContainerService>();
}
}
}
下面的代码显示了我目前所处的位置,可能接近测试的样子(如果当前有点混乱)。我在这里可能会偏离目标,所以任何帮助都会遭遇风暴
using System;
using Moq;
using NUnit.Framework;
using Papermoon.Umbraco.Aldus.Core.Composers;
using Papermoon.Umbraco.Utils.Services;
using Papermoon.Umbraco.Utils.Services.Interfaces;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
using Umbraco.Core.Composing.CompositionExtensions;
using Umbraco.Core.Logging;
namespace Papermoon.Umbraco.Aldus.Core.Tests.Composers
{
[TestFixture]
public class ServicesComposerTests
{
private ServicesComposer _servicesComposer;
[SetUp]
public void SetUp()
{
_servicesComposer = new ServicesComposer();
Current.Factory = new Mock<IFactory>().Object;
}
[Test]
public void Compose_WhenCalled_RegistersContentTypeContainerService()
{
var mockedRegister = Mock.Of<IRegister>();
var logger = new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>());
var typeLoader = new TypeLoader(Mock.Of<IAppPolicyCache>(), "", logger);
var composition = new Composition(mockedRegister, typeLoader, logger, Mock.Of<IRuntimeState>());
_servicesComposer.Compose(composition);
var resolved = Current.Factory.GetInstance<IPapermoonContentTypeContainerService>();
Assert.IsNotNull(resolved);
}
}
}
以下是导致我出现该错误的代码:
[Test]
public void Compose_WhenCalled_RegistersContentTypeContainerService()
{
Func<IFactory, IFactory> factoryFactory = null;
var mockedRegister = Mock.Of<IRegister>();
var mockedFactory = Mock.Of<IFactory>();
// the mocked register creates the mocked factory
Mock.Get(mockedRegister)
.Setup(x => x.CreateFactory())
.Returns(mockedFactory);
Mock.Get(mockedRegister)
.Setup(x => x.Register(It.IsAny<Func<IFactory, IFactory>>(), Lifetime.Singleton))
.Callback<Func<IFactory, IFactory>, Lifetime>((ff, lt) => factoryFactory = ff);
// the mocked factory can invoke the factory factory
Mock.Get(mockedFactory)
.Setup(x => x.GetInstance(typeof(IFactory)))
.Returns(() => factoryFactory?.Invoke(mockedFactory));
var logger = new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>());
var typeLoader = new TypeLoader(Mock.Of<IAppPolicyCache>(), "", logger);
var composition = new Mock<Composition>(mockedRegister, typeLoader, logger, new Mock<IRuntimeState>().Object);
composition.Verify(c => c.Register<IPapermoonContentTypeContainerService, PapermoonContentTypeContainerService>(It.IsAny<Lifetime>()));
}
[测试]
当调用注册表ContentTypeContainerService()时,公共无效组合
{
Func factoryFactory=null;
var mockedRegister=Mock.Of();
var mockedFactory=Mock.Of();
//模拟寄存器创建模拟工厂
Mock.Get(mockedRegister)
.Setup(x=>x.CreateFactory())
.退货(模拟工厂);
Mock.Get(mockedRegister)
.Setup(x=>x.Register(It.IsAny(),life.Singleton))
.回调((ff,lt)=>FactoryFactoryFactory=ff);
//模拟工厂可以调用工厂
Mock.Get(mockedFactory)
.Setup(x=>x.GetInstance(typeof(IFactory)))
.Returns(()=>factoryFactory?.Invoke(mockedFactory));
变量记录器=新的ProfilingLogger(Mock.Of(),Mock.Of());
var typeLoader=new typeLoader(Mock.Of(),“”,logger);
var composition=newmock(mockedRegister、typeLoader、logger、newmock().Object);
composition.Verify(c=>c.Register(It.IsAny());
}
最终,我失败得很惨(可能我的目标定得太高了!),我不能100%确定在这里测试什么。我的想法是,我想测试IPapermoonContentTypeContainerService
在\u serviceComposer.Compose
运行后是否可解析,即它不为null,这确保它已注册到容器中。在哪一点上这可能是不可能的,我想知道是否测试composition.Register()调用code>就足够了(因为实际的注册部分是第三方的,因此不需要测试)。或者,我是不是找错了方向,而这根本不应该被测试
谢谢
Ben是一种静态扩展方法。您不能模拟扩展方法,您需要查看它的源代码&看看它在幕后调用了什么方法
例如,假设我有一个ILogger
,它公开了ILogger.Write(信息级别,字符串消息)
,那么我有一个扩展方法:
public static void Info(this ILoggerlogger, string message) => logger.Write("Info", message);
当对ILogger
的模拟实例调用Info
时,仍会调用扩展方法,并调用模拟的ILogger.Write
从中可以看到,通用扩展正在调用另一个重载—这是您需要设置/验证的重载:
composition.Verify(c => c.Register(typeof(IPapermoonContentTypeContainerService), typeof(PapermoonContentTypeContainerService), It.IsAny<Lifetime>()));
composition.Verify(c=>c.Register(typeof(IPapermoonContentTypeContainerService)、typeof(PapermoonContentTypeContainerService)、It.IsAny());
我不熟悉服务作曲家&怀疑这是不可能的;而不是使用IRegister
(其组合
继承自)将允许您直接模拟合成
,而无需模拟其依赖项…在我看来,umbraco团队应该更改为使用i注册表
参数或类似于i合成
的新合同来定义合成。在这一点上,尝试测试您的DI注册似乎比它的价值更麻烦
public static void Info(this ILoggerlogger, string message) => logger.Write("Info", message);
composition.Verify(c => c.Register(typeof(IPapermoonContentTypeContainerService), typeof(PapermoonContentTypeContainerService), It.IsAny<Lifetime>()));