using Dpz.Core.Entity.Base;

namespace Dpz.Core.Simple.Test;

public class GetterSetterTest
{
    private class Person
    {
        public string? Name { get; set; }
        public int Age { get; set; }
        public string ReadOnly { get; } = "ro";
    }

    [Test]
    public void Setter_And_Getter_For_Reference_Type_Work()
    {
        var setter = PropertyAccessor.GetSetter<Person>(nameof(Person.Name));
        var getter = PropertyAccessor.GetGetter<Person>(nameof(Person.Name));

        Assert.That(setter, Is.Not.Null);
        Assert.That(getter, Is.Not.Null);

        var p = new Person();
        setter!(p, "Alice");
        var value = getter!(p);

        Assert.That(value, Is.EqualTo("Alice"));
    }

    [Test]
    public void Setter_And_Getter_For_Value_Type_Work()
    {
        var setter = PropertyAccessor.GetSetter<Person>(nameof(Person.Age));
        var getter = PropertyAccessor.GetGetter<Person>(nameof(Person.Age));

        Assert.That(setter, Is.Not.Null);
        Assert.That(getter, Is.Not.Null);

        var p = new Person();
        setter!(p, 42);
        var value = getter!(p);

        Assert.That(value, Is.EqualTo(42));
    }

    [Test]
    public void Getter_And_Setter_Are_Cached()
    {
        var s1 = PropertyAccessor.GetSetter<Person>(nameof(Person.Name));
        var s2 = PropertyAccessor.GetSetter<Person>(nameof(Person.Name));
        var g1 = PropertyAccessor.GetGetter<Person>(nameof(Person.Name));
        var g2 = PropertyAccessor.GetGetter<Person>(nameof(Person.Name));

        Assert.That(ReferenceEquals(s1, s2), Is.True);
        Assert.That(ReferenceEquals(g1, g2), Is.True);
    }

    [Test]
    public void Getter_For_Invalid_Property_Is_Null()
    {
        var getter = PropertyAccessor.GetGetter<Person>("NotExists");
        Assert.That(getter, Is.Null);
    }

    [Test]
    public void Setter_For_ReadOnly_Property_Is_Null()
    {
        var setter = PropertyAccessor.GetSetter<Person>(nameof(Person.ReadOnly));
        Assert.That(setter, Is.Null);
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

这是一个使用NUnit测试框架编写的单元测试类,用于测试PropertyAccessor类的功能。让我详细解释这段代码:

代码结构

测试类和测试对象

public class GetterSetterTest
{
    private class Person
    {
        public string? Name { get; set; }     // 可读写的引用类型属性
        public int Age { get; set; }          // 可读写的值类型属性
        public string ReadOnly { get; } = "ro"; // 只读属性
    }
}

Person类作为测试用的模型类,包含了三种不同类型的属性用于测试不同场景。

测试方法详解

1. 引用类型属性测试

[Test]
public void Setter_And_Getter_For_Reference_Type_Work()
  • 测试PropertyAccessor能否正确获取和设置引用类型属性(string)
  • 验证获取的setter和getter不为null
  • 通过setter设置值,再通过getter读取值,验证功能正确性

2. 值类型属性测试

[Test]
public void Setter_And_Getter_For_Value_Type_Work()
  • 测试PropertyAccessor能否正确处理值类型属性(int)
  • 验证逻辑与引用类型测试相同

3. 缓存机制测试

[Test]
public void Getter_And_Setter_Are_Cached()
  • 验证PropertyAccessor是否实现了缓存机制
  • 多次获取同一属性的getter/setter应该返回同一个实例
  • 使用ReferenceEquals检查对象引用是否相同

4. 异常情况测试

[Test]
public void Getter_For_Invalid_Property_Is_Null()
  • 测试当请求不存在的属性时,getter应该返回null
[Test]
public void Setter_For_ReadOnly_Property_Is_Null()
  • 测试当请求只读属性的setter时,应该返回null

PropertyAccessor的推断功能

从测试代码可以推断出PropertyAccessor类具有以下特性:

  1. 泛型支持:支持泛型类型的属性访问
  2. 类型安全:能正确处理引用类型和值类型
  3. 性能优化:实现了缓存机制,避免重复创建accessor
  4. 错误处理:对无效属性名和只读属性有适当的处理
  5. 反射封装:提供了比直接使用反射更简洁的API

使用场景

这种PropertyAccessor通常用于:

  • ORM框架中的对象属性映射
  • 序列化/反序列化操作
  • 动态对象属性访问
  • 配置绑定等场景

整体来说,这是一个设计良好的测试类,覆盖了PropertyAccessor的主要功能点和边界情况。

评论加载中...