Ali*_*hşi 5 c# unit-testing automapper asp.net-core
消息:System.InvalidOperationException:Mapper未初始化.使用适当的配置调用Initialize.如果您正试图通过容器或以其它方式使用映射器实例,请确保您不必静态Mapper.Map方法的任何电话,如果你使用ProjectTo或UseAsDataSource扩展方法,确保你在适当的IConfigurationProvider通实例.
定义映射配置文件(ApplicationMappingProfile.cs)
public class ApplicationMappingProfile : Profile
{
public ApplicationMappingProfile()
{
CreateMap<User, UserListDto>();
CreateMap<Permission, PermissionListDto>();
// add auto mapper mapping configurations here
}
}
Run Code Online (Sandbox Code Playgroud)
注册automapper服务(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;
}
}
Run Code Online (Sandbox Code Playgroud)
创建一个测试服务器以运行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();
}
}
Run Code Online (Sandbox Code Playgroud)
并测试(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);
}
}
Run Code Online (Sandbox Code Playgroud)
此测试方法调用/api/test/GetUsers/使用appservice(PermissionAppService.cs)的方法.此应用程序服务返回使用automapper从实体映射的dto.所以这里发生了异常.
当我删除以下行时:
ServiceCollectionExtensions.UseStaticRegistration = false;
Run Code Online (Sandbox Code Playgroud)
然后我收到以下错误:
消息:System.InvalidOperationException:Mapper已初始化.您必须为每个应用程序域/进程调用一次Initialize.
发生此错误,因为有多个类从ApiTestBase类继承.如果我只运行TestAuthorizedAccessAsync方法,它运行没有问题.
这个问题可能有点复杂,对不起抱歉:)随便问一下你不明白的地方.
它在我运行使用appServices的web api项目时有效
如果我将以下行添加到TestBase构造函数中,则只有一个测试失败而其他测试通过.
public TestBase()
{
lock (ThisLock)
{
Mapper.Reset();
Client = GetTestServer();
}
....
Run Code Online (Sandbox Code Playgroud)
测试库
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();
}
...
Run Code Online (Sandbox Code Playgroud)
UserApplicationServiceTests.cs
public class UserApplicationServiceTests : ApplicationTestBase
{
private readonly IUserAppService _userAppService;
public UserApplicationServiceTests()
{
var userRepository = new Repository<User>(KodkodInMemoryContext);
_userAppService = new UserAppService(userRepository, Mapper);
}
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2270 次 |
| 最近记录: |