安装程序:我已经注册了一个配置服务,该服务从appsettings.json中提取数据,并且运行正常。我还有一个控制器使用该服务从该文件中获取设置,同样,它的工作方式也应该像这样:
public class ApiController : Controller
{
private readonly string _apiUri;
public ApiController(IOptions<Configurator> config)
{
_apiUri = config.Value.ApiSettings.ApiBaseUrl +
config.Value.ApiSettings.ApiVersion;
}
//...
}
现在注意,我是自动化单元测试和asp.net核心的新手。我想做的是消除ApiController对注入服务的依赖,以便我可以使用单独的XUnit测试项目来测试控制器内部的功能,类似于this tutorial中的示例。
为此,我创建了一个模型和接口来表示我的appsettings.json文件的ApiSettings部分:
"ApiSettings": {
"ApiBaseUrl": "https://example.com/api/",
"ApiVersion": "v1/"
}
模型:
public class ApiSettings : IApiSettings
{
public string ApiBaseUri { get; set; }
public string ApiVersion { get; set; }
}
界面:
public interface IApiSettings
{
string ApiBaseUri { get; set; }
string ApiVersion { get; set; }
}
然后我创建了一个依赖于服务来注入设置的类:
public class ApiSettingsBuilder
{
private readonly string _apiUri;
public ApiSettingsBuilder(IOptions<Configurator> config)
{
_apiUri = config.Value.ApiSettings.ApiBaseUrl +
config.Value.ApiSettings.ApiVersion;
}
public string ApiUri { get { return _apiUri; } }
}
问题:如何创建此类的新实例?
public class ApiController : Controller
{
private readonly string _apiUri;
public ApiController()
{
ApiSettingsBuilder builder = new ApiSettingsBuilder(/*What do I do here*/);
_apiUri = builder.ApiUri;
}
public ApiController(IApiSettings settings)
{
//For testing
_apiUri = settings.ApiBaseUrl + settings.ApiVersion;
}
//...
}
此外,我知道这都有些过分,但我仍想得到一个答案,因为它在其他情况下可能很有用。
答案 0 :(得分:3)
您不必出于单元测试的目的而创建新的类,可以使用适当的框架(例如,最小起订量:
var configurator = new Configurator() { ApiBaseUrl = "abc" };
var mock = new Mock<IOptions<Configurator>>();
mock.Setup(ap => ap.Value).Returns(configurator);
然后,您可以将模拟对象传递给构造函数以进行单元测试:
var controller = new ApiController(mock.Object);