using Dpz.Core.Entity.Base.ExpressTreeQuery;

namespace Dpz.Core.Simple.Test;

public class GenerateExpressionTest
{
    // 测试用的请求类
    private class TestRequest
    {
        [QueryFilter(FilterCondition.NotNull)]
        public string? Name { get; set; }

        [QueryFilter(FilterCondition.EqualValue)]
        public int Age { get; set; }

        [QueryFilter(FilterCondition.NotNullOrEmpty)]
        public string? Description { get; set; }

        [QueryFilter(FilterCondition.GtValue)]
        public decimal Price { get; set; }
    }

    // 测试用的实体类
    private class TestEntity
    {
        public string? Name { get; set; }
        public int Age { get; set; }
        public string? Description { get; set; }
        public decimal Price { get; set; }
    }

    [Test]
    public void GenerateConditionExpressionTree_WithNullValues_ShouldReturnTrue()
    {
        // Arrange
        var request = new TestRequest();

        // Act
        var expression = GenerateConditionFilter.GenerateConditionExpressionTree<
            TestEntity,
            TestRequest
        >(request);
        var func = expression.Compile();
        var result = func(new TestEntity());

        // Assert
        Assert.That(result, Is.True);
    }

    [Test]
    public void GenerateConditionExpressionTree_WithValidValues_ShouldReturnCorrectResult()
    {
        // Arrange
        var request = new TestRequest
        {
            Name = "Test",
            Age = 18,
            Description = "Description",
            Price = 100,
        };

        // Act
        var expression = GenerateConditionFilter.GenerateConditionExpressionTree<
            TestEntity,
            TestRequest
        >(request);
        var func = expression.Compile();

        // Assert
        var matchingEntity = new TestEntity
        {
            Name = "Test",
            Age = 18,
            Description = "Description",
            Price = 200,
        };
        Assert.That(func(matchingEntity), Is.True);

        var nonMatchingEntity = new TestEntity
        {
            Name = "Test",
            Age = 17,
            Description = "Description",
            Price = 50,
        };
        Assert.That(func(nonMatchingEntity), Is.False);
    }

    [Test]
    public void GenerateConditionExpressionTree_WithContainsComparison_ShouldWorkCorrectly()
    {
        // Arrange
        var request = new TestRequest { Name = "Test", Description = "Test Description" };

        // Act
        var expression = GenerateConditionFilter.GenerateConditionExpressionTree<
            TestEntity,
            TestRequest
        >(request);
        var func = expression.Compile();

        // Assert
        var entity = new TestEntity { Name = "Test", Description = "Test Description" };
        Assert.That(func(entity), Is.True);
    }

    [Test]
    public void GenerateConditionExpressionTree_WithMultipleEntities_ShouldWorkCorrectly()
    {
        // Arrange
        var request = new TestRequest { Name = "Test", Age = 18 };

        // Act
        var expression = GenerateConditionFilter.GenerateConditionExpressionTree<
            TestEntity,
            TestEntity,
            TestRequest
        >(request);
        var func = expression.Compile();

        // Assert
        var entity1 = new TestEntity { Name = "Test", Age = 18 };
        var entity2 = new TestEntity { Name = "Test", Age = 18 };
        Assert.That(func(entity1, entity2), Is.True);
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

这是一个用于测试表达式树生成功能的单元测试类。让我详细解释一下代码的结构和功能:

代码结构分析

1. 测试用的数据模型

// 请求类 - 用于定义查询条件
private class TestRequest
{
    [QueryFilter(FilterCondition.NotNull)]
    public string? Name { get; set; }

    [QueryFilter(FilterCondition.EqualValue)]
    public int Age { get; set; }

    [QueryFilter(FilterCondition.NotNullOrEmpty)]
    public string? Description { get; set; }

    [QueryFilter(FilterCondition.GtValue)]
    public decimal Price { get; set; }
}

// 实体类 - 被查询的数据对象
private class TestEntity
{
    public string? Name { get; set; }
    public int Age { get; set; }
    public string? Description { get; set; }
    public decimal Price { get; set; }
}

QueryFilter特性说明:

  • NotNull: 检查字段不为null
  • EqualValue: 检查字段值相等
  • NotNullOrEmpty: 检查字符串不为null且不为空
  • GtValue: 检查字段值大于指定值

2. 测试方法详解

测试1:空值条件测试

[Test]
public void GenerateConditionExpressionTree_WithNullValues_ShouldReturnTrue()
  • 目的: 测试当请求对象的所有属性都是默认值时的行为
  • 预期结果: 返回True(表示没有过滤条件,所有实体都匹配)

测试2:有效值条件测试

[Test]
public void GenerateConditionExpressionTree_WithValidValues_ShouldReturnCorrectResult()
  • 测试场景: 设置具体的过滤条件
  • 验证逻辑:
    • matchingEntity: 满足所有条件(Name="Test", Age=18, Description有值, Price=200>100)
    • nonMatchingEntity: 不满足条件(Age=17≠18, Price=50<100)

测试3:包含比较测试

[Test]
public void GenerateConditionExpressionTree_WithContainsComparison_ShouldWorkCorrectly()
  • 目的: 测试字符串包含匹配功能
  • 验证: Name和Description都匹配时返回True

测试4:多实体测试

[Test]
public void GenerateConditionExpressionTree_WithMultipleEntities_ShouldWorkCorrectly()
  • 特点: 使用三个泛型参数的重载方法
  • 目的: 测试同时处理两个实体对象的场景

核心功能

这个测试类主要验证 GenerateConditionFilter.GenerateConditionExpressionTree 方法的功能:

  1. 动态表达式树生成: 根据请求对象的特性标注,动态生成过滤条件的表达式树
  2. 多种过滤条件支持: 支持NotNull、EqualValue、NotNullOrEmpty、GtValue等多种比较操作
  3. 类型安全: 通过泛型确保编译时类型安全
  4. 性能优化: 表达式树编译后可重复使用,避免反射开销

使用场景

这种设计模式通常用于:

  • ORM查询条件构建
  • API查询参数过滤
  • 数据库查询优化
  • 动态查询条件生成

通过特性标注的方式,开发者可以声明式地定义查询条件,框架自动生成对应的表达式树,既提高了开发效率,又保证了类型安全和性能。

评论加载中...