Тест MS с параметром FromBody Web API - PullRequest
0 голосов
/ 20 февраля 2019

У меня есть C # .Net Web API, который я пишу и пытаюсь построить MSTest для одного метода.

Контроллер

     public IHttpActionResult BlahMethod([FromBody] dynamic data)
        {
                string id = data.id;
                List<Property> Props = JsonConvert.DeserializeObject<List<Property>>(data.properties.ToString());
                User existing = _context.MyClass.Where(x => x.Properties.Any(y => y.PropertyLabel == "app" && y.PropertyValue == id)).FirstOrDefault();
                    return Json(existing);
        }

Я пытаюсь проверить этот метод, используя макет, подобный приведенному ниже

Метод тестирования

[TestMethod]
public void AllUsersTest()
{
    var mockSet = new Mock<DbSet<MyClass>>();
    var mockContext = new Mock<DBContext>();
    mockContext.Setup(m => m.MyClass).Returns(mockSet.Object);

    MyController controller = new MyController();
    List<Property> Props = new List<Property>() {
        new Property(){ PropertyLabel = "Nickname", PropertyValue = "TMoney"}
    };
    dynamic data = new TestObject("id", Props);
    var x = controller.BlahMethod(data);
    Assert.IsTrue(true);
}

Классы

public class TestObject {
    public TestObject() { }
    public TestObject(string id, List<Property> props)
    {
        this.id = id;
        this.properties = props;
    }
    public string id { get; set; }
    public List<Property> properties { get; set; } = new List<Property>();

}    
public class Property{
     public string PropertyLabel {get; set;}
     public string PropertyValue {get; set;}
  }

У меня, похоже, проблема с JsonReaderException.По какой-то причине там ошибка говорит о неожиданном характере.Я также попытался отправить динамический объект через, и это также вызвало проблему.Может быть, у кого-нибудь есть советы по поводу лучшего подхода к использованию API в .net с использованием опубликованных данных?

1 Ответ

0 голосов
/ 20 февраля 2019

Ошибка является результатом следующей строки в вашем контроллере:

List<Property> Props = JsonConvert.DeserializeObject<List<Property>>(data.properties.ToString());

В этой строке вы сначала конвертируете свойства в строку, а затем пытаетесь десериализовать строку.Однако преобразование в строку - это не то же самое, что сериализация в JSON.Таким образом, вызов DeserializeObject получает неверную строку и выдает ошибку.

В Web API вы можете определить модель данных, которые вы получаете, как классы, и инфраструктура будет обрабатывать десериализацию для вас.Таким образом, вы можете просто определить класс в вашем проекте, который включает в себя все необходимые свойства.По сути, вы можете переместить класс TestObject из тестового проекта в проект Web API и реализовать действие следующим образом:

public IHttpActionResult BlahMethod([FromBody] TestObject data)
{
  string id = data.id;
  var Props = data.properties;
  User existing = _context.MyClass.Where(x => x.Properties.Any(y => y.PropertyLabel == "app" && y.PropertyValue == id)).FirstOrDefault();
  if (existing == null)
    return NotFound();
  return Ok(existing);
}

Измененное действие действительно определяет необходимые входные данные, используя TestObject в качестве параметра.Если вы вызываете действие с помощью JSON, платформа Web API преобразует его для вас перед вызовом действия.
В этом методе вы работаете непосредственно с данными и также возвращаете существующего пользователя в качестве объекта.Инфраструктура Web API принимает возвращаемый параметр и сериализует его, чтобы вызывающий мог понять формат (обычно в JSON).

Что касается вашего модульного теста, вы создаете образец TestObject, как вы уже сделали, и устанавливаете свойства, как требуется в вашем тестовом примере.Вы вызываете действие напрямую с данными.

...