使用FromBody参数Web API进行MS测试

时间:2019-02-20 07:00:39

标签: c# .net api mocking mstest

我有一个正在编写的C#.Net Web API,并试图为一种方法构建MSTest。

Controlller

     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问题。由于某种原因,错误表明存在意外字符。我也尝试通过发送动态对象,这也引起了问题。也许有人对使用发布的数据使用.net中的API进行模拟的最佳方法有一些建议?

1 个答案:

答案 0 :(得分:2)

该错误是控制器中以下行的结果:

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框架采用return参数并对其进行序列化,以便调用者可以理解格式(通常为JSON)。

对于单元测试,您已经像创建一个示例TestObject一样,并根据测试用例的要求设置了属性。您直接使用数据调用操作。