Search code examples
c#unit-testingconfiguration.net-6.0

How can you make properties mandatory for an options object when using the IOptions pattern?


This requirement comes from a testing perspective. I'm happy with the IOptions pattern in that it should just load what it has from configuration and then you can use validation to ensure the options object has what it needs. However, when testing other parts using said options, it becomes an issue in that you can just new up that options object with as little as is required.

In my case I have my options object below:

public sealed record SomeOptions
{
    public string Name { get; set; }
    public string Description { get;, set; }
    public Uri Location { get; set; }
}

I would like to ensure that whenever a SomeOptions is created in tests that Name and Location are mandatory to mirror what validation would cover in normal circumstances. Having tests using invalid instances of SomeOptions seems like something that could come back and bite me.

Ordinarily I'd encourage this via a constructor but this throws an InvalidOperationException when it tries to build the configuration as it needs a parameterless constructor. What is the best approach here? I've currently stuck a parameterless constructor in with an XML comment saying "DO NOT USE" but this seems woefully inadequate.


Solution

  • If you can migrate to C# 11 (and highly likely .NET 7) you can use the newly introduced required modifier:

    public sealed record SomeOptions
    {
        public required string Name { get; set; }
        public string Description { get; set; }
        public required Uri Location { get; set; }
    }
    

    If not than the only option is to write your own custom analyzer.