gpt4 book ai didi

scala - 如何订购@Before 方法

转载 作者:行者123 更新时间:2023-12-01 12:58:56 25 4
gpt4 key购买 nike

我有一个特性,它添加了几个测试和 before block 。具体实例的@Before block 在特性中的 block 之前运行。糟糕,这意味着我无法截断数据库表然后插入固定装置:

trait DatabaseTest {
@Before
def truncate() {
// "TRUNCATE %s".format(tableName)
}

def tableName
}

class PersonasTest extends DatabaseTest {
@Before
def addPersona() {
// "INSERT INTO %s VALUES (...)".format(tableName)
}


@Test
def testRejectsInsertWhenAlreadyInTable() {
// "INSERT INTO %s VALUES (...)".format(tableName)
}

def tableName = "personas"
}

testRejectsInsertWhenAlreadyInTable 将始终成功,因为执行顺序为:

  • addPersona
  • 截断
  • testRejectsInsertWhenAlreadyInTable

在不对子类施加太多约束的情况下,对@Before block 进行排序的正确方法是什么?我总是可以在特征中声明 truncate,然后在子类中有一个 @Before 方法,但是我必须记住让我的所有子类都调用那个 truncate 方法。

在 Scala 2.9.0.1 上使用 JUnit 4.10。

最佳答案

这样做的正确方法是使用@Rule,扩展@ExternalResource 用于类型前后的行为(在 Java 语法中):

@Rule
public ExternalResource resource= new ExternalResource() {
@Override
protected void before() throws Throwable {
myServer.connect();
};

@Override
protected void after() {
myServer.disconnect();
};
};

您可以使用 @RuleChain(在 4.10 中引入)按顺序将多个 @Rule 链接在一起并排序,同样采用 java 语法:

@Rule
public TestRule chain= RuleChain
.outerRule(new LoggingRule("outer rule")
.around(new LoggingRule("middle rule")
.around(new LoggingRule("inner rule");

有一个警告。您不能在 Scala 中指定公共(public)字段(公共(public)字段用访问器方法包装,并且字段本身变为私有(private))。 JUnit 检查@Rule 是否适用于公共(public)字段。更改 JUnit 代码的修复,以便您可以将 @Rule 应用于方法和字段。

这已经(由我)修复,并已合并到 master 中,但不幸的是,它尚未发布:它将成为 4.11 的一部分。所以你有两个选择:使用 4.11-SNAPSHOT,或者下载 4.10 版本并应用 patch for @Rule .

scala 代码可能类似于:

trait DatabaseTest {
def truncate(): TestRule = {
new ExternalResource() {
override def before() = {
// "TRUNCATE %s".format(tableName)
}
}
}

def extra(): TestRule = {
// return a no-op rule
}

@Rule def testRule() = new RuleChain(truncate(), extra())
def tableName
}

class PersonasTest extends DatabaseTest {
def extra(): TestRule {
new ExternalResource() {
override def before() = {
// "INSERT INTO %s VALUES (...)".format(tableName)
}
}
}

@Test
def testRejectsInsertWhenAlreadyInTable() {
// "INSERT INTO %s VALUES (...)".format(tableName)
}

def tableName = "personas"
}

关于scala - 如何订购@Before 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7986584/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com