当我在特定代码库中编写测试时,我经常需要在新添加的代码之前设置一个静态属性,并在离开时将其重新设置回来。示例
public void SomeMethod(){
val oldVal = Notifier.DoNotify;
Notifier.DoNotify = false;
// Some code...
Notifier.DoNotify = oldVal;
}
我认为这种方式很丑陋,我想要更好的东西,这也使得忘记重新设置值变得更困难。
我尝试煮点东西,结果得到了这个。我看到了一些好处,但这是一个相当啰嗦的解决方案。
public class ValueHolder<T> : IDisposable
{
private readonly Action<T> setter;
private readonly T oldVal;
public ValueHolder(Func<T> getter, T tempVal, Action<T> setter)
{
this.setter = setter;
oldVal = getter();
setter(tempVal);
}
public void Dispose()
{
setter(oldVal);
}
}
然后使用如下
public void SomeMethod(){
using(new ValueHolder<bool>(() => Notifier.DoNotify, false, (b) => Notifier.DoNotify(b)) {
// Do something ...
}
}
有什么好的解决方案吗?
(编辑删除了对测试的引用。似乎分散了我想问的内容)
最佳答案
您可以采取一些措施来使其更容易编写。我会尝试利用您正在使用的任何测试框架来帮助在测试之前和之后运行一些设置/清理代码。但除此之外,还有一些可以减少样板的技巧。
首先,我们可以创建一个辅助类,它将减少创建 ValueHolder<T>
的样板文件。实例。我将使用 LINQ 表达式自动创建 getter 和 setter 委托(delegate),而不是要求调用者传递 getter 和 setter(尽管这在高级情况下仍然有用)。
public class ValueHolder
{
public static ValueHolder<T> Create<T>(Expression<Func<T>> staticProp, T tempVal)
{
var ex = (MemberExpression)staticProp.Body;
var prop = (PropertyInfo)ex.Member;
var getter = (Func<T>)Delegate.CreateDelegate(typeof(Func<T>), prop.GetGetMethod());
var setter = (Action<T>)Delegate.CreateDelegate(typeof(Action<T>), prop.GetSetMethod());
return new ValueHolder<T>(getter, tempVal, setter);
}
}
这使得创作更加简洁
ValueHolder.Create(() => Notify.DoNotify, false);
其次,您可能需要设置其中一些,而大量使用有点难看。我的answer这个问题提供了一种使用继承自 List<T>
的类以稍微简单的方式处理这种情况的方法。这也是IDisposable
。将这些结合起来,您可以使您的设置变得更加简单:
public void SomeTestMethod()
{
// before any state has change.
using (Setup())
{
// Test code.
}
// the cleanup code has run so the state is reset here.
}
private static IDisposable Setup()
{
return new DisposableList() {
ValueHolder.Create(() => Notify.DoNotify, false),
ValueHolder.Create(() => ConnectionManager.MaxConnections, 100),
ValueHolder.Create(() => SomeClass.SomeProp, 2.5),
// etc., I think you get the idea.
};
}
关于c# - 在 C# 中临时存储和重新设置属性值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23949456/