Пользовательский атрибут валидатора работает в модульном тесте, но не в веб-контроллере API? - PullRequest
0 голосов
/ 10 сентября 2018

Атрибут валидации ValidateMinMaxListCountAttribute работает в моем модульном тесте, но не при использовании в рамках веб-API?

Например, в модульном тесте isValid возвращает true, но в контроллере происходит сбой. Я предполагаю какую-то проблему с сериализацией?

У кого-нибудь есть идеи?

[TestCategory("ServiceTests")]
[TestMethod]
public void CallServiceCalc()
{

    var client = new RestClient();
    client.BaseUrl = new Uri("https://localhost:44379");
    client.Authenticator = new HttpBasicAuthenticator("eric.schneider", "password");

    var request = new RestRequest();
    request.Resource = "api/Calculation/Calculate";

    CoralRequest coralReq = new CoralRequest();
    coralReq.ModelId = 1;
    coralReq.ModelName = "2018";
    coralReq.BasePlan = new BeneifitsPlanInputs();
    coralReq.Plans.Add(new BeneifitsPlanInputs());
    request.AddBody(coralReq);

    ValidateMinMaxListCountAttribute va = new ValidateMinMaxListCountAttribute(1, 999);
    bool isValid = va.IsValid(coralReq.Plans);

    IRestResponse response = client.Execute(request);

    Assert.IsTrue(response.StatusCode == System.Net.HttpStatusCode.OK, "Should not be ok");
}

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class ValidateMinMaxListCountAttribute : ValidationAttribute
{
    public ValidateMinMaxListCountAttribute(int minimum, int maximum)

{
    this.MinimumCount = minimum;
    this.MaximumCount = maximum;
}

public int MinimumCount { get; set; }
public int MaximumCount { get; set; }

public override bool IsValid(object value)
{
    var list = value as ICollection;

    if (list != null)
    {
        if (list.Count > MaximumCount) { return false; }
        if (list.Count < MinimumCount) { return false; }
        return true;
        }

        return false;
    }
}


   public class CoralRequest
    {
        public CoralRequest()

    {
        this.Plans = new List<BeneifitsPlanInputs>();
    }


    /// <summary>
    /// 
    /// </summary>
    [ValidateMinMaxListCount(1, 99, ErrorMessage = "Must have between 1 and 99 plans")]
    public IList<BeneifitsPlanInputs> Plans { get; set; }
}

1 Ответ

0 голосов
/ 16 сентября 2018

Основываясь на одном из ваших других вопросов, которые, кажется, связаны, вы показываете, что действие контроллера выглядит следующим образом ...

[HttpGet("{mock}")]
public ActionResult<CoralResult> CalculateMock(CoralRequest mock)

Во время теста выполняется запрос GET, GETзапросы не имеют ТЕЛО, а вы добавляете один к запросу.Это означает, что, скорее всего, модель не заполняется / не привязывается правильно на сервере

Это выглядит как классическая XY проблема

Это действие, скорее всего, должно быть POSTзапросить, если вы хотите получить ТЕЛО запроса, и действие должно быть реорганизовано, чтобы явно указать, откуда должны быть получены данные.

[Route("api/[controller]")]
public class CalculationController: Controller {

    //POST api/Calculation/Calculate
    [HttpPost("[action]")]
    public ActionResult<CoralResult> Calculate([FromBody]CoralRequest model) {
        if(ModelState.IsValid) {
            CoralResult result = new CoralResult();

            //...do something with model and populate result.

            return result;
        }
        return BadRequest(ModelState);
    }

}

Который теперь должен более точно соответствовать тому, что предпринималось втест интеграции

[TestCategory("ServiceTests")]
[TestMethod]
public void CallServiceCalc() {

    var client = new RestClient();
    client.BaseUrl = new Uri("https://localhost:44379");
    client.Authenticator = new HttpBasicAuthenticator("eric.schneider", "password");

    var request = new RestRequest(Method.POST); //<-- POST request
    request.Resource = "api/Calculation/Calculate";
    request.AddHeader("content-type", "application/json");

    CoralRequest coralReq = new CoralRequest();
    coralReq.ModelId = 1;
    coralReq.ModelName = "2018";
    coralReq.BasePlan = new BeneifitsPlanInputs();
    coralReq.Plans.Add(new BeneifitsPlanInputs());
    request.AddJsonBody(coralReq); //<-- adding data as JSON to body of request

    IRestResponse response = client.Execute(request);

    Assert.IsTrue(response.StatusCode == System.Net.HttpStatusCode.OK, "Should be HttpStatusCode.OK");
}

Теперь средство связывания модели должно иметь возможность проверять модель после ее связывания и передачи в действие.

Ссылка Связывание модели в ASP.NET Core

...