Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.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#_Xunit_Options_Appsettings - Fatal编程技术网

C# 在单元测试中获取配置

C# 在单元测试中获取配置,c#,xunit,options,appsettings,C#,Xunit,Options,Appsettings,我不知道如何通过遵循IOptions模式来获得我正在使用的一些配置 我要测试的服务是下一个: private readonly Dictionary<ErrorType, ErrorObject> _errors; public UserService( ...(Many services)... IOptions<Dictionary<ErrorType, ErrorObject>&

我不知道如何通过遵循IOptions模式来获得我正在使用的一些配置

我要测试的服务是下一个:

        private readonly Dictionary<ErrorType, ErrorObject> _errors;

        public UserService(
            ...(Many services)...
            IOptions<Dictionary<ErrorType, ErrorObject>> errors)
        {
            ...
            _errors = errors.Value;
        }
所以这工作得很好,但是我现在的问题是我不知道如何实例化它,模拟它,或者在我的测试类中注入它,因为即使我注入它,我也不能在这样的类中解析它,并且我总是得到null。 我在测试夹具中这样注入了它(与我的真实注入模块中相同):

servicecolection.Configure(x=>Configuration.GetSection(“错误”).Bind(x));
我必须正确地注入包含所有错误的IConfiguration,我只是无法为构造函数创建所需的字典

在这里,我得到的错误没有任何问题:

IConfiguration Configuration = ioCModule.ServiceProvider.GetRequiredService<IConfiguration>();
            var errorsConfig = Configuration.GetSection("Errors");
IConfiguration Configuration=ioCModule.ServiceProvider.GetRequiredService();
var errorsConfig=Configuration.GetSection(“错误”);
现在我要弄清楚在这份声明中应该写些什么:

var _options = Options.Create<Dictionary<BusinessErrorType, BusinessErrorObject>>();
var\u options=options.Create();
我在测试夹具中这样注入了它(与我的真实注入模块中相同):

您已经尝试注入字典,而您的类希望获得选项。尝试注册和注入选项,很可能会成功

现在我要弄清楚在这份声明中应该写些什么:

var _options = Options.Create<Dictionary<BusinessErrorType, BusinessErrorObject>>();
选项
对象只是一些现成值的持有者,或者 没有什么您必须使用以下两种方法构造
选项
对象 它会忽略该值,或者什么也不给(结果是选项为空) 对象)。如果使用不带任何参数的
Options.Create()
,则会创建一个空对象,仅此而已。只需在此之前创建字典并将其传递给Options 学院

var dict=newdictionary();
dict.Add(“UserNotFound”,新的BusinessErrorObject(..);
dict.Add(“错误密码”,新的BusinessErrorObject(..);
var _options=options.Create(dict);
//现在您有了它:\ u选项,其中包含一些数据
如果你指望在选项中使用Bind(),我怀疑它会像那样工作,因为Bind是用来填充数据结构的,配置是从设置文件读取的,而Options只是一个shell,类似于“Nullable”,它的存在只是为了传递信息。。。然而,我认为您可以首先创建一个字典,然后用配置(即绑定)填充它,然后用选项包装刚刚填充的字典,然后在IoC中注册该选项对象,这样您的用户服务就可以获得它的配置。。然而,我不能100%确定Bind是否足够智能,可以填充通用字典。你需要自己测试,不幸的是,我手头没有任何aspnetcore项目可供使用

编辑/旁注:

我有点惊讶你在单元测试中构建/设置整个IoC。在创建单元测试时,您希望尽可能地剪切/模拟依赖项。也就是说,没有IoC,这会给测试带来另一组问题/失败等

我的意思是,我希望您的单元测试看起来像:

[Test]
public void FoobarizingTheBaz()
{
    var mock1 = ....;
    var mock2 = ....;
    var mock3 = ....;
    var ... = ....;
    var mockN = ....;

    var dict = new Dictionary<....>();
    dict.Add(....);
    dict.Add(....);
    var mockOptions = Options.Create<...>(dict);

    var tested = new UserService(
        mock1, mock2, mock3, ... mockN, mockOptions
    );

    var result = tested.FoobarizeTheBaz();

    // assert...
}
[测试]
公共无效FoobarizingTheBaz()
{
var mock1=。。。。;
var mock2=。。。。;
var mock3=。。。。;
var…=。。。。;
var mockN=。。。。;
var dict=新字典();
dict.Add(…);
dict.Add(…);
var mockOptions=Options.Create(dict);
var tested=newuserservice(
mock1、mock2、mock3、…mockN、mockOptions
);
var result=tested.FoobarizeTheBaz();
//断言。。。
}
这是一个单元测试。只有被测试对象被实例化,rest被模拟,并且您只提供绝对必要的内容。当然,我不得不编写大量的setup/mock/etc,而不是依靠IoC来自动实现它们,但是一旦编写了mock,您就可以将它们带到一些公共代码中,测试类init、fixture等并重用它们

我是说,没有appsettings.json。没有i配置。没有国际奥委会等等

如果您想测试有多少组件相互交互,那么它更像是一个集成测试。在这种情况下,您可能希望在集成测试设置中使用自定义appsettings.json和IOptions查看哪些触摸。然而,请注意,aspnetcore中的“集成测试”通常意味着测试您的服务如何响应请求并检查响应,因此您将在本文中看到这一点。不过,关于IOptions的部分内容应该会有所帮助

我在测试夹具中这样注入了它(与我的真实注入模块中相同):

您已经尝试注入字典,而您的类希望获得选项。尝试注册和注入选项,很可能会成功

现在我要弄清楚在这份声明中应该写些什么:

var _options = Options.Create<Dictionary<BusinessErrorType, BusinessErrorObject>>();
选项
对象只是一些现成值的持有者,或者 没有什么您必须使用以下两种方法构造
选项
对象 它会忽略该值,或者什么也不给(结果是选项为空) 对象)。如果使用不带任何参数的
Options.Create()
,则会创建一个空对象,仅此而已。只需在此之前创建字典并将其传递给Options 学院

var dict=newdictionary();
dict.Add(“UserNotFound”,新的BusinessErrorObject(..);
dict.Add(“错误密码”,新的BusinessErrorObject(..);
var _options=options.Create(dict);
//现在您有了它:\ u选项,其中包含一些数据
如果你指望在选项中使用Bind(),我怀疑它会像那样工作,因为Bind是用来填充数据结构的,配置是从设置文件读取的,而Options只是一个shell,类似于“Nullable”,它的存在只是为了传递信息。。。然而,我认为您可以首先创建一个字典,然后用配置(即绑定)填充它,然后用选项包装刚刚填充的字典,然后在IoC中注册该选项对象,这样您的用户服务就可以获得它的配置。。但是,我不能100%确定我是否
[Test]
public void FoobarizingTheBaz()
{
    var mock1 = ....;
    var mock2 = ....;
    var mock3 = ....;
    var ... = ....;
    var mockN = ....;

    var dict = new Dictionary<....>();
    dict.Add(....);
    dict.Add(....);
    var mockOptions = Options.Create<...>(dict);

    var tested = new UserService(
        mock1, mock2, mock3, ... mockN, mockOptions
    );

    var result = tested.FoobarizeTheBaz();

    // assert...
}