Instantiating IOptions<> in xunit

[亡魂溺海] 提交于 2019-12-04 07:41:06

You could use OptionsWrapper<T> class to fake your configuration. Then you can pass in this object to your class that you want to test. That way you don't have to use DI or read the real configuration.

Something like this:

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

I have encountered a similar problem (using xUnit), after some struggle, I worked it out.

The answer is so late, but should be helpful for others.


For your Question:

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)
        // ...
    }
}

Also, you should copy "appSettings.json" to your project root folder.

You can create an instance of IOptions<FoodList> using the Options.Create method:

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

In a unit test, you typically don't use Dependency Injection, since it's you who controls the creation of the tested object.

To supply a suitable object that implements IOptions<FoodList> you can implement a fake class with the desired behavior yourself, or use some mocking framework to configure the instance on the fly, for example Moq.

As suggested by the other answers, in your test class you can create an options instance just for testing.

You can do it like this;

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

And then call it like this;

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

var response = foodStore.Act();

Assert.Equal("whatever", response);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!