仿真枚举继承:最佳选择和实践
我正在设计一个测试应用程序(使用NUnit),它必须通过网页导航(通过Selenium Webdriver API)。我想使用枚举建模站点结构,以便能够通过此枚举来告诉方法在哪里导航(特别是NUnit方法)。仿真枚举继承:最佳选择和实践
this.NavigateTo(Page.HomePage);
这是一个强烈的要求(有一个枚举类型的地方)主要是因为NUnit不能传递非原始类型。举例来说,这个语法是不可能的,因为NUnit的页必须原始或枚举:
static class Page{
public static Page HomePage;
public static Page UserAccountPage;
}
/* ... later ... */
[TestCase(Page.HomePage)]
void TestMethod(Page p) { ...
我也想用相同的枚举或最喜欢做基本的继承,像
interface IPage{}
interface IPageNavigatable : Page {}
interface IPageUserRelated : Page {}
interface IWildcardPage : Page {}
enum Page{
HomePage : IPageNavigatable,
UserAccountPage : IPageNavigatable IPageUserRelated,
ErrorPage : /* none */,
AnyPage : IWildcardPage
}
然后,我将能够做出非常有趣的方法,如
bool IsCurrentPage(IWildcardPage p);
void LoginThenNavigate(String user, String pw, IPageUserRelated p);
Page WhereAmI(); /* and use this value with IsAssignableFrom */
我知道C#禁止枚举继承(我还是不明白这一点选择,但这不是我现在的问题),我已经读了几个解决方法,包括一个类重新编码从头开始的枚举机制;没有一个看起来满意。
我最好的想法是使用一个复杂的类与内部枚举和一些公共布尔值。不是很satisfctory ...
public class Page{
enum Pages { /* you know them */}
public Page.Pages InnerPage;
public bool isWildcard, isUserRelated, ...;
public Page(Page.Pages p){
this.InnerPage = p;
switch (p){
case ...:
case ...:
this.isWildcard = true;
break;
/* ... */
}
}
}
/* NUnit calls */
[TestCase(Page.Pages.HomePage)]
void TestMethod(Page.Pages p) { ...
此外,在一个完美的世界,我喜欢“链接”我的枚举或-所以打字用绳子或URI的值,这样我就可以写的东西,如:
enum Page{
HomePage : IPageNavigatable = "/index.php",
UserAccountPage : IPageNavigatable IPageUserRelated = "/user.php",
ErrorPage : /* none */ = (String) null,
AnyPage : IWildcardPage = (String) null
}
/* ... */
Page p;
Selenium.Webdriver drv;
drv.Navigate().GoToUrl(new Url(p.ToString()));
这对我来说是一个棘手的问题。任何人都可以帮忙
编辑:正如Chris指出的,线索是NUnit(通过属性)可以接受Object类型的参数。使用这种方法,可能有一种方法可以用我的继承结构实现几乎无代码的对象,并重新编码枚举机制的一部分(以及链接到URL字符串)。
不是我梦想的解决方案,但可能工作...
你确定他们一定是原语(顺便说一下,我们调用.NET世界的值类型或结构)? This page似乎暗示,你是有限的原因是因为在.NET属性的固有限制,而这又被描述here的:
属性参数被限制在 以下类型的恒定值:
简单类型(布尔,字节,字符,短,整型,长整型,浮点,双)
串
系统。型
枚举
对象(的参数类型的对象的属性参数必须是上述类型之一的恒定值。)上述任何类型的
一维阵列
这表明,我认为以下将工作:
static class Pages {
public const String HomePage = "Home Page";
public const String UserAccountPage = "User Account Page";
}
[TestCase(Pages.HomePage)]
void TestMethod(Page p) { ...
您是否尝试过只是做一个自定义类,而不是一个枚举?
如
public class Page
{
public IPageNavigatable HomePage = "/index.php";
public IPageNavigatable UserAccountPage = "/user.php";
public Type ErrorPage = null;
public IWildcardPage AnyPage = null;
}
这(提供的成员将统计ic)可能是我最后的回退,但有一个主要缺陷:ErrorPage.equals(AnyPage)== true – PPC 2012-02-10 20:45:29
只有属性的限制。我将无法在使用String作为输入的方法中使用类型识别(在您的示例中,TestMethod将以字符串作为输入 – PPC 2012-02-10 20:50:23