gpt4 book ai didi

c# - Asp.net 核心 2.1 单元测试自动映射器?

转载 作者:太空狗 更新时间:2023-10-29 23:12:21 26 4
gpt4 key购买 nike

错误信息

Message: System.InvalidOperationException : Mapper not initialized. Call Initialize with appropriate configuration. If you are trying to use mapper instances through a container or otherwise, make sure you do not have any calls to the static Mapper.Map methods, and if you're using ProjectTo or UseAsDataSource extension methods, make sure you pass in the appropriate IConfigurationProvider instance.

应用项目

定义映射配置文件(ApplicationMappingProfile.cs)

public class ApplicationMappingProfile : Profile
{
public ApplicationMappingProfile()
{
CreateMap<User, UserListDto>();
CreateMap<Permission, PermissionListDto>();
// add auto mapper mapping configurations here
}
}

注册自动映射器服务(ApplicationServiceCollectionExtensions.cs)

public static class ApplicationServiceCollectionExtensions
{
public static IServiceCollection AddKodkodApplication(this IServiceCollection services)
{
services.AddAutoMapper();

//todo: add conventional registrar
services.AddTransient<IUserAppService, UserAppService>();
services.AddTransient<IPermissionAppService, PermissionAppService>();

return services;
}
}

单元测试项目

创建一个测试服务器来运行 Startup.cs (ApiTestBase.cs)

public class ApiTestBase : TestBase
{
protected static HttpClient Client;

public ApiTestBase()
{
//if this is true, Automapper is throwing exception
ServiceCollectionExtensions.UseStaticRegistration = false;

Client = GetTestServer();
}

private static HttpClient GetTestServer()
{
if (Client != null)
{
return Client;
}

var server = new TestServer(
new WebHostBuilder()
.UseStartup<Startup>()
.ConfigureAppConfiguration(config =>
{
config.SetBasePath(Path.GetFullPath(@"../../.."));
config.AddJsonFile("appsettings.json", false);
})
);

return server.CreateClient();
}
}

并测试 (AccountTests.cs)。

public class AccountTests : ApiTestBase
{
[Fact]
public async Task TestAuthorizedAccessAsync()
{
var responseLogin = await LoginAsTestUserAsync();
var responseContent = await responseLogin.Content.ReadAsAsync<OkObjectResult>();
var responseJson = JObject.Parse(responseContent.Value.ToString());
var token = (string)responseJson["token"];

var requestMessage = new HttpRequestMessage(HttpMethod.Get, "/api/test/GetUsers/");
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
var responseGetUsers = await Client.SendAsync(requestMessage);
Assert.Equal(HttpStatusCode.OK, responseGetUsers.StatusCode);

var users = await responseGetUsers.Content.ReadAsAsync<PagedList<UserListDto>>();
Assert.True(users.Items.Count > 0);
}
}

此测试方法调用使用应用服务 (PermissionAppService.cs) 的 /api/test/GetUsers/ 方法。此应用程序服务返回使用自动映射器从实体映射的 dto。所以这里发生了异常。

当我删除以下行时:

ServiceCollectionExtensions.UseStaticRegistration = false;

然后我得到以下错误:

Message: System.InvalidOperationException : Mapper already initialized. You must call Initialize once per application domain/process.

出现此错误是因为有多个类继承自 ApiTestBase 类。如果我只运行 TestAuthorizedAccessAsync 方法,它运行没有问题。

这个问题可能有点复杂,对此深表歉意:) 有什么不明白的地方尽管问。

PROJECT SOURCE

编辑

当我运行使用 appServices 的 web api 项目时它有效

编辑2

如果我向 TestBase 构造函数添加以下行,则只有一个测试失败而其他测试通过。

public TestBase()
{
lock (ThisLock)
{
Mapper.Reset();
Client = GetTestServer();
}

....

enter image description here

最佳答案

  • 禁用自动映射器静态注册并将其初始化以作为参数传递给应用服务

TestBase.cs

public class TestBase
{
private static Dictionary<string, string> _testUserFormData;

protected readonly IMapper Mapper;
protected readonly KodkodDbContext KodkodInMemoryContext;
protected readonly ClaimsPrincipal ContextUser;
protected readonly HttpClient Client;
protected async Task<HttpResponseMessage> LoginAsTestUserAsync()
{
return await Client.PostAsync("/api/account/login",
_testUserFormData.ToStringContent(Encoding.UTF8, "application/json"));
}

public TestBase()
{
// disable automapper static registration
ServiceCollectionExtensions.UseStaticRegistration = false;

// Initialize mapper
Mapper = new Mapper(
new MapperConfiguration(
configure => { configure.AddProfile<ApplicationMappingProfile>(); }
)
);
Client = GetTestServer();

_testUserFormData = new Dictionary<string, string>
{
{"email", "testuser@mail.com"},
{"username", "testuser"},
{"password", "123qwe"}
};

KodkodInMemoryContext = GetInitializedDbContext();
ContextUser = GetContextUser();
}
...
  • 将映射器作为参数传递给应用服务

UserApplicationServiceTests.cs

public class UserApplicationServiceTests : ApplicationTestBase
{
private readonly IUserAppService _userAppService;

public UserApplicationServiceTests()
{
var userRepository = new Repository<User>(KodkodInMemoryContext);
_userAppService = new UserAppService(userRepository, Mapper);
}
...

关于c# - Asp.net 核心 2.1 单元测试自动映射器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50717370/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com