使用NUnit进行asp.net核心6.0 web api单元测试



我正在尝试为我的项目中的控制器操作方法创建简单的web api测试。我已经在我的解决方案中创建并添加了测试项目。并在测试项目中添加Nunit nuget包。

我试图测试的控制器是这样的:

[ApiController]
[Route("[controller]")]
public class HomeController : ControllerBase
{

private readonly IConfiguration _configuration;
private readonly IHostEnvironment _hostEnvironment;
private readonly ILogger<HomeController> _logger;
private BaseDataAccess _datatAccess = new BaseDataAccess()

public HomeController(ILogger<HomeController> logger, IConfiguration configuration, IHostEnvironment hostEnvironment)
{
_logger = logger;
_configuration = configuration;
_hostEnvironment = hostEnvironment;
}

[HttpGet("GetInfo/{code}")]
public IActionResult GetInfo(string code)
{
List<InfoModel> infos = new List<InfoModel>();
int isNumber;
if (String.IsNullOrEmpty(code) || !int.TryParse(code, out isNumber))
{
_logger.LogInformation(String.Format("The code pass as arguments to api is : {0}", code));

return BadRequest("Invalid code");
}
try
{

_logger.LogDebug(1, "The code passed is" + code);
SqlConnection connection = _datatAccess.GetConnection(_configuration, _hostEnvironment);
string sql = string.Format ("SELECT * from table1 where code={0}", code);
DataTable dt = _datatAccess.ExecuteQuery(connection,CommandType.Text, sql);
if (dt != null && dt.Rows.Count > 0)
{
foreach (DataRow dr in dt.Rows)
{
infos.Add(new InfoModel
{
ID = dr["id"].ToString(),
code = dr["code"].ToString()
});
}
}

}
catch (Exception ex)
{
_logger.LogError(4, String.Format("Error Message: " + ex.Message + "n" + ex.StackTrace));

return BadRequest("There is something wrong.Please contact the administration.");
}

return new OkObjectResult(infos);
}
}

现在,当我尝试创建单元测试时,我需要将配置、主机环境和记录器从我的TestHomeController传递到HomeController。我不知道如何实例化这些设置并传递给控制器:

using NUnit.Framework;
using Microsoft.AspNetCore.Mvc;
using MyApi.Models;
using MyApi.Controllers;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace MyApi.Tests
{
[TestFixture]
public class TestHomeController: ControllerBase
{
private readonly IConfiguration _configuration; //How to instantiate this so it is not null
private readonly IHostEnvironment _hostEnvironment ;//How to instantiate this so it is not null
private ILogger<HomeController> _logger;//How to instantiate this so it is not null

[Test]
public void GetInfo_ShouldReturnAllInfo()
{
var controller = new HomeConteoller(_logger, _configuration, _hostEnvironment);
var result = controller.GetInfo("11");
var okObjectResult = (OkObjectResult)result;
//Assert
okObjectResult.StatusCode.Equals(200);

}
}

}

感谢您的帮助和建议。

可能,你有startup.cs,不是吗?如果你要测试一个控制器,那么你需要构建一个应用程序的完整实例。在这里,我举了一个例子,说明如果你有Startup.cs.,你可以如何测试你的代码

public class SUTFactory : WebApplicationFactory<Startup>
{
protected override IHostBuilder CreateHostBuilder()
{
return Program.CreateHostBuilder(null);
}
}
public class TestControllerTests
{
private SUTFactory factory;
private HttpClient _client;
public TestControllerTests() 
{
factory = new SUTFactory();
_client = factory.CreateClient();
}
[Test]
public async Task GetPatientInterviewID_ShouldReturnAllInterviewID()
{
// Arrange
var id = "11";
// Act
var result = await _client.GetAsync($"Home/GetInfo/{id}");
// Assert
Assert.AreEqual(System.Net.HttpStatusCode.OK, result.StatusCode);
}
}

这个例子更接近集成测试,而不是单元测试。如果你想进行单元测试,那么你需要做以下事情

  1. BaseDataAccess _dataAccess这是一个特定的实现,它不能被模拟(与ILogger、IHostEnvironment等相比(

  2. 将所有代码从控制器移到一个单独的类中,并测试这个类。

最新更新