仿真枚举继承:最佳选择和实践

问题描述:

我正在设计一个测试应用程序(使用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) { ... 
+1

只有属性的限制。我将无法在使用String作为输入的方法中使用类型识别(在您的示例中,TestMethod将以字符串作为输入 – PPC 2012-02-10 20:50:23

您是否尝试过只是做一个自定义类,而不是一个枚举?

public class Page 
{ 
    public IPageNavigatable HomePage = "/index.php"; 
    public IPageNavigatable UserAccountPage = "/user.php"; 
    public Type ErrorPage = null; 
    public IWildcardPage AnyPage = null; 
} 
+0

这(提供的成员将统计ic)可能是我最后的回退,但有一个主要缺陷:ErrorPage.equals(AnyPage)== true – PPC 2012-02-10 20:45:29