在xunit中实例化IOptions<>

问题描述 投票:0回答:6

我正在尝试为一个类(在 .net Core 项目中)编写一个 xunit 测试,如下所示:

public Class FoodStore:IFoodStore
{
    FoodList foodItems;

    public FoodStore(IOptions<FoodList> foodItems)
    {
        this.foodItems = foodItems;
    }

    public bool IsFoodItemPresentInList(string foodItemId)
    {
        //Logic to search from Food List
    }
}`

注意:

FoodList
实际上是一个json文件,包含数据,在Startup类中加载和配置。

如何编写具有适当依赖注入的 xunit 测试来测试

IsFoodItemPresentInList
方法?

dependency-injection asp.net-core xunit xunit.net asp.net-core-1.0
6个回答
13
投票

您可以使用

IOptions<FoodList>
方法创建
Options.Create
的实例:

var foodListOptions = Options.Create(new FoodList());

11
投票

您可以使用

OptionsWrapper<T>
类来伪造您的配置。然后您可以将此对象传递给您要测试的类。这样你就不必使用 DI 或读取真实配置。

类似这样的:

var myConfiguration = new OptionsWrapper<MyConfiguration>(new MyConfiguration
            {
                SomeConfig = "SomeValue"
            });
var yourClass = new YourClass(myConfiguration);

7
投票

我遇到了类似的问题(使用xUnit),经过一番努力,我解决了。

答案这么晚了,但应该对其他人有帮助。


对于你的问题:

public Class FoodStoreTest
{
    private readonly IConfigurationRoot _configuration;
    private readonly IServiceProvider _serviceProvider;

    public FoodStoreTest(){
            // read Json
            var configBuilder = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddEnvironmentVariables();
            _configuration = configBuilder.Build();

            // SetUp DI
            var services = new ServiceCollection();
            services.AddOptions(); // this statement is required if you wanna use IOption Pattern.

            services.Configure<YuntongxunOptions>(_configuration.GetSection("yuntongxun"));
            _serviceProvider = services.BuildServiceProvider();
    }

    [Fact]
    public void GetFootItemOption()
    {
         IOption<FoodList> optionAccessor = _serviceProvider.GetService<IOptions<FoodList>>();
         FoodList footListOptions = optionAccessor.value;
         Assert.NotNull(footListOptions)
        // ...
    }
}

此外,您应该将“appSettings.json”复制到项目根文件夹。


3
投票

在单元测试中,您通常不使用依赖注入,因为是您控制测试对象的创建。

要提供实现

IOptions<FoodList>
的合适对象,您可以自己实现具有所需行为的伪类,或者使用一些模拟框架动态配置实例,例如 Moq


1
投票

正如其他答案所建议的,在您的测试类中,您可以创建一个仅用于测试的选项实例。

你可以这样做;

public class FakeFoodList : IOptions<FoodList>
{
    public FoodList Value
    {
        get
        {
            return new FoodList(); // TODO: Add your settings for test here.
        }
    }
}

然后这样称呼它;

var foodOptions = new FakeFoodList();
var foodStore = new FoodStore(foodOptions);

var response = foodStore.Act();

Assert.Equal("whatever", response);

0
投票

您可以执行以下操作:

private Mock<IOptions<SomeSettings>> _someSettings;

并且在测试方法中:

`_someSettings = 新模拟();

_someSettings.Setup(o => o.Value).Returns(new SomeSettings

{

 ClientId = "723jsisksokskskos",

 ClientSecret = "sjhs;~jspkasjd;asdj;asdpqwoepqwe",

 ConnectionStrings = new List<ConnectionStrings>

 {
     new ConnectionStrings { Acronym = "A1"  },
     new ConnectionStrings { Acronym = "A2"  }
 }

}); `

模型结构:

`公共类 SomeSettings : ISomeSettings

{

 public const string ConfigurationName = nameof(SomeSettings);

 public string ClientId { get; set; }

 public string ClientSecret { get; set; }

 public string QueryCount { get; set; }

 public List<ConnectionStrings> ConnectionStrings { get; set; }

}`

© www.soinside.com 2019 - 2024. All rights reserved.