模拟枚举继承:最佳选择&;实践
本文关键字:amp 实践 最佳选择 枚举 继承 模拟 | 更新日期: 2023-09-27 18:24:17
我正在设计一个测试应用程序(使用NUnit),该应用程序必须在网页中导航(通过Selenium Webdriver API)。我想使用枚举对站点结构进行建模,以便能够通过这个枚举告诉方法在哪里导航(尤其是NUnit方法)。
this.NavigateTo(Page.HomePage);
这是一个强烈的要求(在某个地方有一个枚举类型),主要是因为不能向NUnit传递非基元类型。例如,这种语法对NUnit来说是不可能的,因为Page必须是原语或enum:
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#禁止枚举继承(我仍然不理解这个选择,但现在这不是我的问题),我已经阅读了一些解决方案,包括一个从头开始重写枚举机制的类;没有一个看起来令人满意。
我的最佳想法是使用一个带有内部枚举和一些公共布尔值的复杂类。不是很满意。。。
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世界中称这些值类型或结构)?这个页面似乎意味着你受到限制的原因是.NET属性中固有的限制,而这些属性又在这里描述:
属性参数被限制为以下类型:
简单类型(bool、byte、char、short、int、long、float和double)
字符串
系统类型
enums
对象(对象类型的属性参数的自变量必须是上述类型之一的常数值。)
任何上述类型的一维阵列
这向我表明以下方法可行:
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;
}