单元测试Web API的新功能。我正在编写单元测试以测试控制器,而我必须模拟Iconfiguration。appsettings,json有一个名为“ AppSettings”的部分,我正在尝试模拟它。
另外,mock.setup在控制器中返回空值,导致其失败。
这是我的控制器:
private readonly ILogger _logger;
private readonly IConfiguration _configuration;
private readonly ICarPairingTable PairingTable;
private readonly ICarDealerSettingsTable DealerSettingsTable;
static AppSettings appSettings = null;
public CarController(IConfiguration configuration, ICarPairingTable carPairingTable, ICarDealerSettingsTable settingsTable)
{
_configuration = configuration;
appSettings = configuration.Get<AppSettingsModel>().AppSettings;
PairingTable = carPairingTable;
DealerSettingsTable = settingsTable;
}
[HttpGet]
public ActionResult Get(string id){
string DealerId ="";
DealerId = PairingTable.GetDealerId(id).Result;
if (string.IsNullOrEmpty(DealerId))
{
result = new ReturnResult
{
status = "Fail",
data = "ID is invalid"
};
return NotFound(result);
}
SettingsInfo info = DealerSettingsTable.GetSettingsInfo(DealerId).Result;
if (info == null)
{
result = new ReturnResult
{
status = "Fail",
data = "Not Found
};
return NotFound(result);
}
result = new ReturnResult
{
status = "Success",
data = info
};
return Ok(result);
}
这是我的单元测试:
[Fact]
public void Test1()
{
var mockConfig = new Mock<IConfiguration>();
var configurationSection = new Mock<IConfigurationSection>();
configurationSection.Setup(a => a.Value).Returns("testvalue");
mockConfig.Setup(a => a.GetSection("AppSettings")).Returns(configurationSection.Object);
var mock1 = new Mock<ICarPairingTable>();
mock1.Setup(p => p.GetDealerId("456")).ReturnsAsync("123");
var mock2 = new Mock<ICarDealerSettingsTable>();
SettingsInfo mockSettings = new SettingsInfo()
{
DealerId = "123",
Name="Dealer1"
};
mock2.Setup(p => p.GetSettingsInfo("123")).ReturnsAsync(()=>mockSettings);
CarController controller = new CarController(mockConfig.Object, mock1.Object, mock2.Object);
var result = controller.Get("456");
//Dont know what to assert
}
编写了单元测试,但不确定我的方法是否正确,将不胜感激。
真的不应该注射IConfiguration
。根据控制器使用配置的方式,您应该在启动时向服务集合注册设置
Startup.ConfigureServices
//...
AppSettings appSettings = Configuration.Get<AppSettingsModel>().AppSettings;
services.AddSingleton(appSettings);
//...
并明确地将设置注入控制器
//...
private readonly AppSettings appSettings = null;
public CarController(AppSettings appSettings , ICarPairingTable carPairingTable, ICarDealerSettingsTable settingsTable) {
this.appSettings = appSettings;
PairingTable = carPairingTable;
DealerSettingsTable = settingsTable;
}
//...
因此,现在在对控制器进行单元测试时,您可以初始化所需类的实例,并在执行单元测试时提供该实例。
参考显式依赖原则
您似乎还混在一起了async-await和阻止类似的调用.Result
。
我建议您将动作一直保持异步
[HttpGet]
public async Task<ActionResult> Get(string id){
string DealerId = await PairingTable.GetDealerId(id);
if (string.IsNullOrEmpty(DealerId)) {
var result = new ReturnResult {
status = "Fail",
data = "ID is invalid"
};
return NotFound(result);
}
SettingsInfo info = await DealerSettingsTable.GetSettingsInfo(DealerId);
if (info == null) {
var result = new ReturnResult {
status = "Fail",
data = "Not Found"
};
return NotFound(result);
}
var result = new ReturnResult {
status = "Success",
data = info
};
return Ok(result);
}
这样,最终可以正确安排单元测试以验证预期的行为
[Fact]
public async Task Should_Return_Ok_ReturnRsult() {
//Arrange
var id = "456";
var dealerId = "123";
SettingsInfo expected = new SettingsInfo() {
DealerId = dealerId,
Name="Dealer1"
};
var pairingMock = new Mock<ICarPairingTable>();
pairingMock.Setup(p => p.GetDealerId(id)).ReturnsAsync(dealerId);
var dealerSettingsMock = new Mock<ICarDealerSettingsTable>();
dealerSettingsMock.Setup(p => p.GetSettingsInfo(dealerId)).ReturnsAsync(() => expected);
CarController controller = new CarController(new AppSettings(), pairingMock.Object, dealerSettingsMock.Object);
//Act
var actionResult = await controller.Get(id);
var actual = actionResult as OkObjectResult;
//Assert (using FluentAssertions)
actual.Should().NotBeNull();
actual.Value.Should().BeOfType<ReturnResult>();
var actualResult = actual.Value as ReturnResult;
actualResult.data.Should().BeEquivalentTo(expected);
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句