我正在尝试创建一个自定义属性,该属性将以某种 AOP 方式工作(不幸的是,我无法访问 postsharp,而且我对 Unity 也不是很熟悉)。它有 AttributeUsage.Method ,并在其构造函数中配置测试环境的某些部分(从 app.config 中提取一些信息并调用一些配置环境的 exe)。
它有效,除了现在,当我构建解决方案时,该属性被执行 - 这是不可取的。
有没有办法创建不在编译时执行的自定义属性?
编辑> 我想一个示例用法可能会有所帮助:
public void Scenario1Tests
{
[Test]
[Environment(Environments.A)]
public void Scenario1TestA()
{
Assert.Something();
}
[Test]
[Environment(Environments.Any)]
public void Scenario1TestB()
{
Assert.SomethingElse();
}
}
// Most tests will be written environment independent, some must not
public enum Environments
{
A,
B,
Any
};
[AtrributeUsage(AttributeTargets.Method)]
public void Environment : Attribute
{
public Environment(Environments env)
{
// lots of test can have this attribute, requirement is
// that it is only configured once as it is a lengthy configuration
if (this.EnvironmentIsAlreadyConfigured())
return;
this.GetSettingsFromAppConfig();
Process.Start(/* ... */); // can take 20 mins+
}
public Environment()
: this(Environments.Any)
{
}
}
通常的方法是严格使用属性作为标记。您在构造函数中对其进行配置,但不执行任何操作。然后,在运行时,您通过反射检查方法,从属性中提取配置信息,并根据该信息采取适当的操作。
例如,如果您想要一个在执行方法之前检查参数是否为 null 的属性,您可以像这样创建它:
[AttributeUsage(AttributeTargets.Method)]
public class CheckArgumentsNullAttribute : Attribute
{
public CheckArgumentsNullAttribute() { }
}
然后,将您的方法标记为这样:
[CheckArgumentsNull]
public Foo(object o) { Console.WriteLine(o.ToString()); }
然后,在您的代码中获取Foo
通过反射的方法,并检查它的属性:
MethodInfo m = typeof(FooClass).GetMethod("Foo");
if (m.GetCustomAttributes(typeof(CheckArgumentsNullAttribute), false).Length > 0)
{
// Check parameters for null here
}
Update:由于您在 MSTest 运行该方法的情况下需要这个,因此您应该看一下本文 http://callumhibbert.blogspot.com/2008/01/extending-mstest.html,其中讨论了如何挂钩测试过程。基本上,你需要从ContextBoundObject
,并拦截方法调用以执行您想要的属性处理。
Update 2:考虑到该属性的作用,我可能只会将环境设置设置为一个方法,并从适当的测试开始时调用它。我不认为拥有一个属性会给你带来那么多好处。或者,您可以按环境划分灯具,并在灯具设置/拆卸中执行环境设置/拆卸。无论哪种方式都可能比尝试让 AOP 在这里工作要容易得多,尤其考虑到该属性的“一次执行”性质。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)