微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

单元测试中的 .NET Core 依赖注入 - 具有多个具体实现的接口 - Func<string, IInterface>

如何解决单元测试中的 .NET Core 依赖注入 - 具有多个具体实现的接口 - Func<string, IInterface>

我需要您的帮助,以便在 .net Core 控制台应用程序中使用单元测试方法来处理 Moq。 道歉,如果有人问过这个问题,但我尝试过但找不到答案。

有三个实现一个接口的类

public class MailNotification : ISendNotification
{
    public bool SendNotification()
    {
        return true;
    }
}

public class EmailNotification : ISendNotification
{
    public bool SendNotification()
    {
        return true;
    }
}

public class SmsNotification : ISendNotification
{
    public bool SendNotification()
    {
        return true;
    }
 }

在 Program.cs 文件中,我们有:

        private static IServiceCollection ConfigureServices()
    {
        IServiceCollection services = new ServiceCollection();

        var config = LoadConfiguration();
        services.AddSingleton(config);

        services.AddTransient<IUser,User>();
        services.AddTransient<Something>();
        services.AddTransient<MailNotification>();
        services.AddTransient<EmailNotification>();
        services.AddTransient<SmsNotification>();

        //multiply concrete implementation of an Interface
        services.AddTransient<Func<string,ISendNotification>>(serviceProvider => key =>
        {
            switch (key)
            {
                case "Mail":
                    return serviceProvider.GetService<MailNotification>();
                case "Email":
                    return serviceProvider.GetService<EmailNotification>();
                default:
                    return serviceProvider.GetService<SmsNotification>();
            }
        });

        return services;
    }

类看起来像这样:

    public class Something
{
    private readonly IConfiguration config;
    private readonly IUser user;
    private readonly Func<string,ISendNotification> sendMsg;

    public Something(IConfiguration config,IUser user,Func<string,ISendNotification>  send)
    {
        this.config = config;
        this.user = user;
        this.sendMsg = send;
    }

    public bool ProcessUser()
    {
        bool result;
        switch (user.PreferredCommunication.ToString())
        {
            case "Mail":
                  result = sendMsg(NotificationType.Mail.ToString()).SendNotification();
                break;
            case "Email":
                  result = sendMsg(NotificationType.Email.ToString()).SendNotification();
                break;

            default:
                result = sendMsg (NotificationType.SMS.ToString()).SendNotification();
                break;
        }

        return result;
    }
}

这是单元测试类

    public class UnitTest1
{
    private readonly ITestOutputHelper outPutHelper;
    private readonly IConfiguration config;

    public UnitTest1(ITestOutputHelper helper)
    {
        this.outPutHelper = helper;
        //get path to appsettings file,assembly location
        string codeBase = Assembly.GetExecutingAssembly().CodeBase;
        UriBuilder uri = new UriBuilder(codeBase);
        string path = Uri.UnescapeDataString(uri.Path);
        string projectPath = Path.GetDirectoryName(path);

        config = new ConfigurationBuilder().SetBasePath(projectPath).AddJsonFile("appsettings.json").Build();

    }
    [Fact]
    [Trait("Category","Unit")]
    public void ProcessUser_MailNotification_True()
    {
        //Arrange
        Mock<ISendNotification> mockNotify = new Mock<ISendNotification>();
        mockNotify.Setup(x => x.SendNotification()).Returns(true);
        Mock<IUser> mockUser = new Mock<IUser>();
        mockUser.Setup(x => x.TruncateName(It.IsAny<string>()));

        Func<string,ISendNotification> func = () => {
            return new Mock<"Mail",ISendNotification>();
        }; //< -- help help here 
           //The error is Delegate'Func<string,ISendNotification>' does not take 0 arguments

        //Act
        var sut = new Something(config,mockUser.Object,mockNotify.Object); //< -- help help here 
        //The error is Arugment 3: cannot convert from 'ISendNotification' to System.Func<string,ISendNotification>'
    }
}

非常感谢您的帮助!

解决方法

未正确声明委托

//...

Func<string,ISendNotification> send = (string key) => mockNotify.Object;

//...

并且委托也是需要传递给被测对象的东西

//...

var sut = new Something(config,mockUser.Object,send);

//...

从那里可以进行测试来断言预期的行为

//...

//Act
bool actual = sut.ProcessUser();

//Assert - FluentAssertions
actual.Should().BeTrue();

但基于被测成员中使用的依赖项,

//...

switch (user.PreferredCommunication.ToString())

//...

需要进一步设置以允许被测成员完成。但是由于原始问题中没有提供该细节,我将无法指定该值应该是什么。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?