如何在网络核心测试项目中使用应用程序
本文关键字:应用程序 项目 测试 网络 核心 | 更新日期: 2023-09-27 18:13:22
我已经设法从appsettings.json
文件中添加AppSettings在我的Api项目中,像这样
ConfigureServices()
函数中的Startup.cs
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
Controller.cs
private readonly AppSettings _AppSettings;
public UserProfilesController(IOptions<AppSettings> appSettings)
{
_AppSettings = appSettings.Value;
}
但是我不知道如何为我的测试项目做到这一点。我的测试项目中没有Startup.ts
。那么,如何在测试项目中以同样的方式添加应用程序呢?
单单元测试
[Test]
public void Post_Should_Create_A_Single_UserProfile()
{
// Arrange
var profile = Dummy.GenerateCreateUserProfileDto();
MyMvc
.Controller<UserProfilesController>()
.Calling(c => c.Post(profile))
.ShouldReturn()
.Ok()
.WithResponseModelOfType<UserProfileDto>()
.Passing(target =>
{
target.Should().NotBeNull(because: "a record is expected here");
target.Id.Should().BeGreaterThan(0, because: "a id is expected");
target.ShouldBeEquivalentTo(profile, opt => opt
.Excluding(c => c.Id)
.Excluding(c => c.CreatedOn)
.Excluding(c => c.ModifiedOn),
because: "the record returned is expected to be the same as the record inserted");
// Clean up
_Repo.Delete(target.Id);
});
}
My post function
[HttpPost]
public async Task<IActionResult> Post([FromBody]CreateUserProfileDto profile)
{
using (var fileManager = new FileManager())
using (var manager = new UserProfilesRepository())
{
var mapped = Mapper.Map<UserProfile>(profile);
// Only save the profile image if one is selected
if (!string.IsNullOrEmpty(profile.Image))
{
try
{
var result = fileManager.SaveProfileImage(
profile.Image,
_AppSettings.Profile.AbsolutePath,
_AppSettings.BaseUrl,
_AppSettings.Profile.RelativePath
);
mapped.FilePath = result.AbsolutePath;
mapped.ProfilePicture = result.RelativePath;
}
catch (Exception ex)
{
return StatusCode(500);
}
}
manager.Save(mapped);
return Ok(Mapper.Map<UserProfileDto>(mapped));
}
}
您正在模拟MVC控制器来测试它。这样,您应该通过模拟的appSettings
对象创建UserProfilesController
。
另一个选项是启动应用程序,使用Startup.cs
类对其进行测试。我从未使用过nUnit,但在xUnit中,我像这样配置我的测试项目:
TestServer testServer = new TestServer(new WebHostBuilder().UseEnvironment("Development").UseStartup<Startup>());
由于我使用的是Development
环境,所以我还需要在我的测试项目中使用appsettings.Development.json
文件。
testServer.CreateClient().PostAsync(string requestUri, HttpContent content)
编辑:TestServer from Microsoft package:
"Microsoft.AspNetCore.TestHost": "1.0.0"
所以,它应该可以很好地与nUnit一起工作。
您看到的问题是使用mytesting模拟框架的产物。它为控制器的依赖项(IOptions<AppSettings>
实例)创建一个带有模拟值的控制器。这个模拟将返回没有特别配置的任何属性的默认(空)值。
如果这是一个单元测试,你实际上不希望通过使用ConfigurationBuilder
等从appsettings加载来测试它。相反,您应该在测试中提供AppSettings
对象作为依赖项,并显式定义值。
MyTested.AspNetCore.Mvc
using MyTested.AspNetCore.Mvc.DependencyInjection;
[Test]
public void Post_Should_Create_A_Single_UserProfile()
{
// Arrange
var profile = Dummy.GenerateCreateUserProfileDto();
MyMvc
.Controller<UserProfilesController>()
.WithOptions(options => options
.For<AppSettings>(settings => settings.Cache = true))
.Calling(c => c.Post(profile))
.ShouldReturn()
.Ok()
}
原始答案:MyTested。WebApi
例如,你可以这样做:
using Microsoft.Extensions.Options;
[Test]
public void Post_Should_Create_A_Single_UserProfile()
{
// Arrange
var profile = Dummy.GenerateCreateUserProfileDto();
var mockedSettings = new AppSettings
{
MyValue = "the test value"
}
MyMvc
.Controller<UserProfilesController>()
.WithResolvedDependencyFor<IOptions<AppSettings>>(Options.Create(mockedSettings))
.Calling(c => c.Post(profile))
.ShouldReturn()
.Ok()
}