gpt4 book ai didi

c# - 具有授权 ASP.NET Core 2.0 Web API 的单元测试 Controller

转载 作者:行者123 更新时间:2023-11-30 19:53:18 25 4
gpt4 key购买 nike

我有一个 Controller :

public class InvitationsController: Controller {
private readonly IMapper _mapper;
private readonly IInvitationManager _invitationManager;
private readonly UserManager<MyAppUser> _userManager;

public InvitationsController(
IInvitationManager invitationManager,
IMapper mapper,
UserManager<MyAppUser> userManager,
IJobManager jobManager
) {
_invitationManager = invitationManager;
_mapper = mapper;
_userManager = userManager;
}
[Authorization]
GetInvitationByCode(string code) { ... }

我正在尝试使用 Xunit 和 Moq 编写单元测试。这是我的测试的实现:

  public class InvitationsControllerTests {

private Mock<IInvitationManager> invitationManagerMock;
private Mock<UserManager<MyAppUser>> userManagerMock;
private Mock<IMapper> mapperMock;
private InvitationsController controller;

public InvitationsControllerTests() {
invitationManagerMock = new Mock<IInvitationManager>();
userManagerMock = new Mock<UserManager<MyAppUser>>();

mapperMock = new Mock<IMapper>();
controller = new InvitationsController(invitationManagerMock.Object,
mapperMock.Object,
userManagerMock.Object);
}

[Fact]
public async Task GetInvitationByCode_ReturnsInvitation() {

var mockInvitation = new Invitation {
StoreId = 1,
InviteCode = "123abc",
};

invitationManagerMock.Setup(repo =>
repo.GetInvitationByCodeAsync("123abc"))
.Returns(Task.FromResult(mockInvitation));

var result = await controller.GetInvitationByCode("123abc");

Assert.Equal(mockInvitation, result);
}

我认为我没有正确使用模拟功能。特别是 UserManager。我找不到关于使用 Moq 测试受 [Authorize] 保护的 Controller 的明确答案。运行我的测试时,它抛出一个异常

        controller = new InvitationsController(invitationManagerMock.Object,
mapperMock.Object,
userManagerMock.Object);

上面写着:

CaSTLe.DynamicProxy.InvalidProxyConstructorArgumentsException: '无法实例化类的代理:Microsoft.AspNetCore.Identity.UserManager`1[[MyApp.api.Core.Models.MyAppUser, MyApp.api, Version=1.0.0.0, Culture=中性,PublicKeyToken=null]]。找不到无参数的构造函数。”

最佳答案

您不是在进行单元测试;你是集成测试。当您发现自己设置了一万个模拟只是为了运行一个方法时,这是一个很好的迹象,这是一个集成测试。此外,诸如授权之类的事情仅作为请求生命周期的一部分发生;如果不执行实际请求,就无法对其进行测试,这再次意味着您正在进行集成测试。

因此,使用 test host .

private readonly TestServer _server;
private readonly HttpClient _client;

public MyTestClass()
{
_server = new TestServer(new WebHostBuilder()
.UseStartup<Startup>());
_client = _server.CreateClient();
}

[Fact]
public async Task GetInvitationByCode_ReturnsInvitation() {

var mockInvitation = new Invitation {
StoreId = 1,
InviteCode = "123abc",
};

var response = await _client.GetAsync("/route");
response.EnsureSuccessStatusCode();

var responseString = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<Invitation>(responseString);

// Compare individual properties you care about.
// Comparing the full objects will fail because of reference inequality
Assert.Equal(mockInvitation.StoreId, result.StoreId);
}

如果您需要构建数据以返回正确的结果,只需使用 in-memory database provider .使用它进行集成测试的最简单方法是指定一个新环境,如“测试”。然后,在您的启动中,在配​​置上下文时,在环境上分支并在环境为“测试”时使用内存中提供程序(而不是 SQL Server 或其他)。然后,在为集成测试设置测试服务器时,只需添加 .UseEnvironment("Test")之前 .UseStartup<Startup>() .

关于c# - 具有授权 ASP.NET Core 2.0 Web API 的单元测试 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49908658/

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