gpt4 book ai didi

c# - 创建单元测试以确保不变性

转载 作者:太空狗 更新时间:2023-10-29 20:46:58 26 4
gpt4 key购买 nike

我设计了一个 immutable class ,因为我想为它提供值(value)语义。我在类的评论部分写了一个提示

//"这个类是不可变的,在向它添加新功能时不要更改它。"

但我知道,有时其他团队成员会忽略这些评论,所以我想创建一个单元测试作为额外的保障。知道如何做到这一点吗?是否可以通过反射检查一个类以确保只有构造函数更改它的内部状态?

(使用 C# 2.0 和 NUnit,如果这对任何人都很重要的话)。

最佳答案

一个示例来支持我关于如何使用 FieldInfo.IsInitOnly 递归地测试不变性的评论。

可能有更多特殊情况需要考虑,比如我如何处理 string,但我相信它只会给出假阴性,即会告诉你一些不可变的东西,而不是其他方式周围。

逻辑是,每个字段都必须是readonly 并且本身是不可变类型。请注意,它不会处理自引用类型或循环引用。

using System;
using System.Linq;
using System.Reflection;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace ImmutableTests
{
[TestClass]
public class AssertImmutableTests
{
[TestMethod]
public void Is_int_immutable()
{
Assert.IsTrue(Immutable<int>());
}

[TestMethod]
public void Is_string_immutable()
{
Assert.IsTrue(Immutable<string>());
}

[TestMethod]
public void Is_custom_immutable()
{
Assert.IsTrue(Immutable<MyImmutableClass>());
}

[TestMethod]
public void Is_custom_mutable()
{
Assert.IsFalse(Immutable<MyMutableClass>());
}

[TestMethod]
public void Is_custom_deep_mutable()
{
Assert.IsFalse(Immutable<MyDeepMutableClass>());
}

[TestMethod]
public void Is_custom_deep_immutable()
{
Assert.IsTrue(Immutable<MyDeepImmutableClass>());
}

[TestMethod]
public void Is_propertied_class_mutable()
{
Assert.IsFalse(Immutable<MyMutableClassWithProperty>());
}

private static bool Immutable<T>()
{
return Immutable(typeof(T));
}

private static bool Immutable(Type type)
{
if (type.IsPrimitive) return true;
if (type == typeof(string)) return true;
var fieldInfos = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
var isShallowImmutable = fieldInfos.All(f => f.IsInitOnly);
if (!isShallowImmutable) return false;
var isDeepImmutable = fieldInfos.All(f => Immutable(f.FieldType));
return isDeepImmutable;
}
}

public class MyMutableClass
{
private string _field;
}

public class MyImmutableClass
{
private readonly string _field;
}

public class MyDeepMutableClass
{
private readonly MyMutableClass _field;
}

public class MyDeepImmutableClass
{
private readonly MyImmutableClass _field;
}

public class MyMutableClassWithProperty
{
public string Prop { get; set; }
}
}

关于c# - 创建单元测试以确保不变性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5417082/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com