首页 > 解决方案 > 如何使用无数的 switch 语句改进测试?

问题描述

我需要测试从搜索返回的数据是否正确。可以使用多个运算符进行搜索(术语、前缀、通配符等),可以搜索多个字段(名字、姓氏、电子邮件、地址等),当然还有任何搜索参数(''John''、''Smith '', ''john.smith@gmail.com'') 可以输入。在我的测试中,我得到了很多 switch 语句,我想知道这是否可以接受?

这是一个示例测试,用于操作员“term”(所有其他测试也基本上看起来像这样):

[Theory]
[InlineData("term", "firstName", "John")]
[InlineData("term", "email", "@gmail")]
public void Contains_String(string _operator, string field, string value)
{
  string response = FakeSearch.GetResponse(_operator, field, value);

  var result = JsonConvert.DeserializeObject<Rootobject>(response);

  foreach (var employee in result.Hits.HitsArray)
  {
    switch (field)
    {
      case "firstName":
        Assert.True(employee.Source.FirstName.Contains(value, StringComparison.CurrentCultureIgnoreCase));
        break;
      case "lastName":
        Assert.True(employee.Source.LastName.Contains(value, StringComparison.CurrentCultureIgnoreCase));
        break;
      case "phone":
        Assert.True(employee.Source.Phone.Contains(value);
        break;
      case "email":
        Assert.True(employee.Source.Email.Contains(value, StringComparison.CurrentCultureIgnoreCase));
        break;
    }
  }
}

public static class FakeSearch
{
  public static string GetResponse(string _operator, string field, string value)
  {
    string query = GenerateQuery(_operator, field, value);

    return GetData(query);
  }

  public static string GenerateQuery(string _operator, string field, string value)
  {
    QueryRootobject searchObj = new QueryRootobject();
    searchObj.Query = new Query();
    searchObj.Query.Bool = new Bool();
    searchObj.Query.Bool.Must = new Must[1];
    searchObj.Query.Bool.Must[0] = new Must();

    switch (_operator)
    {
      case "term":
        searchObj.Query.Bool.Must[0].Term = new Term();
        switch (field)
        {
          case "firstName":
            searchObj.Query.Bool.Must[0].Term.FirstName = value;
            break;
          case "lastName":
            searchObj.Query.Bool.Must[0].Term.LastName = value;
            break;
          case "phone":
            searchObj.Query.Bool.Must[0].Term.Phone = value;
            break;
          case "email":
            searchObj.Query.Bool.Must[0].Term.Email = value;
            break;
        }
        break;
      case "prefix":
        searchObj.Query.Bool.Must[0].Prefix = new Prefix();
        switch (field)
        {
          case "firstName":
            searchObj.Query.Bool.Must[0].Prefix.FirstName = value;
            break;
          case "lastName":
            searchObj.Query.Bool.Must[0].Prefix.LastName = value;

            // and so on
        }
      case "wildcard":
        // and so on
}

可以/应该以某种方式改进吗?所有的 switch 语句似乎都太多了。也许他们在测试中没问题,但是GenerateQuery方法可以改进吗?如果是这样,怎么办?

标签: c#asp.net

解决方案


我想你可以创建一个代表表。

var map = new Dictionary<string,Func<Employee,string>>
{
    { "firstName", e => e.Source.FirstName },
    { "lastName",  e => e.Source.LastName },
    { "phone",     e => e.Source.Phone },
    { "email",     e => e.Source.Email }
};

然后你可以放弃 switch/case 语句而只使用委托。

var func = map[field];
foreach (var employee in result.Hits.HitsArray)
{
    Assert.True(func(employee).Contains(value, StringComparison.CurrentCultureIgnoreCase));
}

推荐阅读