如何测试具有 re-direct 的端点?

How to test an endpoint that has a re-direct?

我使用以下端点来确认电子邮件地址:

public ConfirmEmailResponse Get(ConfirmEmail req)
{
    var cacheItem = Cache.Get<ConfirmEmailCacheItem>(req.Token);
    if (cacheItem == null)
    {
        base.Response.AddHeader("Location", $"/mail-confirm??confirmed=false");
        base.Response.StatusCode = 302;
        return ConfirmEmailResponse.GetExpiredResponse();
    }

    var domain = _settings.GetRequiredString("site:frontend");

    var user = (IUserAuth)Db.LoadSingleById<UserAuthCustom>(cacheItem.UserId);

    user.UpdateToVerified(_authRepository);

    Cache.Remove(req.Token);
    Cache.Remove($"email-confirm:{user.Id}");

    base.Response.AddHeader("Location", $"/mail-confirm?confirmed=true");
    base.Response.StatusCode = 302;

    return new ConfirmEmailResponse
    {
        Success = true,
        PublicMessage = "Email has been confirmed"
    };
}

我正在尝试为此过程编写测试,但 re-direction 导致我为测试构建的 AppHost 出现问题。

如果我试试这个:

var client = CreateClient();

var email = (EmailSenderMock)AppHost.Resolve<IEmailSender>();
var token = email.EmailMessages.First().ContentValues["token"];

var confirm = new ConfirmEmail{ Token = token };

var confirmResponse = client.Get(confirm);

然后 SS 生成“未找到”异常。我必须删除 header 和状态代码才能获得响应。

我尝试在没有客户端的情况下直接测试服务,如下所示:

var email = (EmailSenderMock)AppHost.Resolve<IEmailSender>();
var confirmService = AppHost.Resolve<UserEmailServices>();
var token = email.EmailMessages.First().ContentValues["token"];

var confirm = new ConfirmEmail{ Token = token };

confirmResponse = confirmService.Get(confirm)

但现在 base.Request 为空,因此它抛出异常。

测试包含 re-direct 的服务的正确方法是什么?

如果重定向是针对浏览器的,您的测试应该通过请求 HTML 响应来模拟浏览器。

因为这不是一个普通的服务客户端请求,您应该使用像 HTTP Utils 这样的通用 HTTP 客户端,例如:

var url = baseUrl.CombineWith(new ConfirmEmail { Token = token }.ToGetUrl());
var body = url.GetStringFromUrl(accept: MimeTypes.Html,
    requestFilter: req => req.AllowAutoRedirect = false,
    responseFilter: res =>
    {
        Assert.That(res.StatusCode, Is.EqualTo(HttpStatusCode.Redirect));
        Assert.That(res.Headers[HttpHeaders.Location],
            Is.EqualTo(...));
    });