Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用第三方对象实例化测试代码_C#_Unit Testing_Nunit_Moq_Umbraco - Fatal编程技术网

C# 使用第三方对象实例化测试代码

C# 使用第三方对象实例化测试代码,c#,unit-testing,nunit,moq,umbraco,C#,Unit Testing,Nunit,Moq,Umbraco,对于单元测试来说是个新手,我尝试着对一段代码进行一些简单的测试,如果它不存在的话,我会获取或创建一个模板(在Umbraco 8中) 该方法非常简单,当调用Initialise时,它将获取模板,如果模板不存在,则创建模板: using Umbraco.Core.Composing; using Umbraco.Core.Models; using Umbraco.Core.Services; namespace Papermoon.Umbraco.Aldus.Core.Components {

对于单元测试来说是个新手,我尝试着对一段代码进行一些简单的测试,如果它不存在的话,我会获取或创建一个模板(在Umbraco 8中)

该方法非常简单,当调用Initialise时,它将获取模板,如果模板不存在,则创建模板:

using Umbraco.Core.Composing;
using Umbraco.Core.Models;
using Umbraco.Core.Services;

namespace Papermoon.Umbraco.Aldus.Core.Components
{
    public class TemplateComponent : IComponent
    {
        private readonly IFileService _fileService;

        public TemplateComponent(IFileService fileService)
        {
            _fileService = fileService;
        }

        public void Initialize()
        {
            ITemplate blogTemplate = _fileService.GetTemplate("aldusBlog");

            if (blogTemplate == null)
            {
                blogTemplate = new Template("Aldus Blog", "aldusBlog");

                _fileService.SaveTemplate(blogTemplate);
            }
        }

        public void Terminate() { }
    }
}
行,没问题

我正在尝试编写一些测试,首先检查是否调用了
\u fileService.GetTemplate

第二个测试应该检查是否调用了
\u fileService.SaveTemplate()
,如果它返回null

using Moq;
using NUnit.Framework;
using Papermoon.Umbraco.Aldus.Core.Components;
using Umbraco.Core.Models;
using Umbraco.Core.Services;

namespace Papermoon.Umbraco.Aldus.Core.Tests.Components
{
    [TestFixture]
    public class TemplateComponentTests
    {
        private Mock<IFileService> _fileService;

        private TemplateComponent _component;

        [SetUp]
        public void SetUp()
        {
            _fileService = new Mock<IFileService>();

            _component = new TemplateComponent(_fileService.Object);
        }

        [Test]
        public void Initialise_WhenCalled_GetsBlogTemplate()
        {
            _component.Initialize();

            _fileService.Verify(s => s.GetTemplate("aldusBlog"), Times.Once);
        }

        [Test]
        public void Initialise_BlogTemplateDoesNotExist_CreateTemplate()
        {
            _fileService
                .Setup(s => s.GetTemplate("aldusBlog"))
                .Returns((ITemplate) null);

            _component.Initialize();

            _fileService.Verify(s => s.SaveTemplate(It.Is<ITemplate>(p => p.Alias == "aldusBlog"), -1), Times.Once());
        }
    }
}
我假设这是因为我没有任何上下文导致我认为需要模拟
ITemplate
。然而,因为
新模板(“Aldus博客”,“Aldus博客”)将始终被调用,它将始终抛出此错误


显然,代码不是防弹的,那么我如何重构它以使其可测试?

第三方类可能与不存在的实现问题紧密耦合,或者在单独进行单元测试时未进行配置

将创建的对象抽象到工厂中

public interface ITemplateFactory {
    ITemplate Create(string name, string alias);
}
谁的实现可以在运行时注入

public class DefaultTemplateFactory : ITemplateFactory {
    public ITemplate Create(string name, string alias) {
        return new Template(name, alias);
    }
}
前提是它在启动期间在合成根目录下注册

这现在允许组件松散耦合,远离实现问题

public class TemplateComponent : IComponent {
    private readonly IFileService fileService;
    private readonly ITemplateFactory templateFactory;

    public TemplateComponent(IFileService fileService, ITemplateFactory templateFactory) {
        this.fileService = fileService;
        this.templateFactory = templateFactory;
    }

    public void Initialize() {
        ITemplate blogTemplate = fileService.GetTemplate("aldusBlog");

        if (blogTemplate == null) {
            blogTemplate = templateFactory.Create("Aldus Blog", "aldusBlog");

            fileService.SaveTemplate(blogTemplate);
        }
    }

    public void Terminate() { }
}
隔离测试时,可根据需要更换

[TestFixture]
public class TemplateComponentTests {

    private Mock<IFileService> fileService;
    private Mock<ITemplateFactory> templateFactory;
    private TemplateComponent component;
    string templateAlias = "aldusBlog";

    [SetUp]
    public void SetUp() {
        //Arrange
        fileService = new Mock<IFileService>();

        templateFactory = new Mock<ITemplateFactory>();
        templateFactory.Setup(_ => _.Create(It.IsAny<string>(), It.IsAny<string>()))
            .Returns((string name, string alias) => 
                Mock.Of<ITemplate>(_ => _.Alias == alias && _.Name == name)
            );

        component = new TemplateComponent(fileService.Object, templateFactory.Object);
    }

    [Test]
    public void Initialise_WhenCalled_GetsBlogTemplate() {
        //Act
        component.Initialize();
        //Assert
        fileService.Verify(s => s.GetTemplate(templateAlias), Times.Once);
    }

    [Test]
    public void Initialise_BlogTemplateDoesNotExist_CreateTemplate() {
        //Act
        component.Initialize();
        //Assert
        fileService.Verify(s => s.SaveTemplate(It.Is<ITemplate>(p => p.Alias == templateAlias), 0), Times.Once());
    }
}
[TestFixture]
公共类TemplateComponentTests{
私有模拟文件服务;
私营模拟样板厂;
私有模板组件;
字符串templateAlias=“aldusBlog”;
[设置]
公共作废设置(){
//安排
fileService=newmock();
templateFactory=new Mock();
templateFactory.Setup(=>wk.Create(It.IsAny(),It.IsAny()))
.Returns((字符串名称、字符串别名)=>
Mock.Of(=>u.Alias==别名&&&u.Name==名称)
);
component=新的TemplateComponent(fileService.Object,templateFactory.Object);
}
[测试]
public void初始化\u调用时\u GetsBlogTemplate(){
//表演
初始化();
//断言
验证(s=>s.GetTemplate(templateAlias),Times.Once);
}
[测试]
public void Initialise_blogtemplatedoesnotextist_CreateTemplate(){
//表演
初始化();
//断言
验证(s=>s.SaveTemplate(It.Is(p=>p.Alias==templateAlias),0),Times.Once();
}
}

第三方类可能与一个实现问题紧密耦合,而当单独进行单元测试时,该问题并不存在。将创建的对象抽象到工厂中。
[TestFixture]
public class TemplateComponentTests {

    private Mock<IFileService> fileService;
    private Mock<ITemplateFactory> templateFactory;
    private TemplateComponent component;
    string templateAlias = "aldusBlog";

    [SetUp]
    public void SetUp() {
        //Arrange
        fileService = new Mock<IFileService>();

        templateFactory = new Mock<ITemplateFactory>();
        templateFactory.Setup(_ => _.Create(It.IsAny<string>(), It.IsAny<string>()))
            .Returns((string name, string alias) => 
                Mock.Of<ITemplate>(_ => _.Alias == alias && _.Name == name)
            );

        component = new TemplateComponent(fileService.Object, templateFactory.Object);
    }

    [Test]
    public void Initialise_WhenCalled_GetsBlogTemplate() {
        //Act
        component.Initialize();
        //Assert
        fileService.Verify(s => s.GetTemplate(templateAlias), Times.Once);
    }

    [Test]
    public void Initialise_BlogTemplateDoesNotExist_CreateTemplate() {
        //Act
        component.Initialize();
        //Assert
        fileService.Verify(s => s.SaveTemplate(It.Is<ITemplate>(p => p.Alias == templateAlias), 0), Times.Once());
    }
}