我想简化我的ScalaTest套件的代码。 我的大部分测试都有一个产生一些Assertion
-s的主体,然后还需要执行一些清理,这些清理在概念上是副作用,但是如果这些清理中的一些产生异常,我希望以该异常失败测试。 所以我才开始简化测试看起来像一个下面:隐式转换器可以有一个名称参数吗?
"Admin" should "be able to create a new team" in{
val attempt=Try{
When("Admin opens the Teams view")
TeamsPage.open
And("creates a new team")
TeamsPage.createNewTeam(tempTeam)
Then("this team is shown in the list")
TeamsPage.isParticularTeamShownInTeamList(tempTeam.name) shouldBe true
}
val cleanUp = Try(TeamsPage.cleanUpTeam(tempTeam))
attempt.flatMap(r => cleanUp.map(_ => r)).get
}
相当不错,但我想有一点不太样板。所以,我从这样的事情开始:
class FollowUp(block: => Assertion){
def andThen[T](followUp: =>T):Assertion = {
val start = Try(block)
val followUpAttempt = Try(followUp)
start.flatMap(r => followUpAttempt.map(_ => r)).get
}
}
object FollowUp{
implicit def assertionToFollowUp(a: => Assertion):FollowUp = new FollowUp(a)
}
class TeamManagementTest extends ADMPSuite with AbilityToManageUsers{
import FollowUp._
val tempTeam = Team("Temp QA Team")
"Admin" should "be able to create a new team" in{
{
When("Admin opens the Teams view")
TeamsPage.open
And("creates a new team")
TeamsPage.createNewTeam(tempTeam)
Then("this team is shown in the list")
TeamsPage.isParticularTeamShownInTeamList(tempTeam.name) shouldBe false
} andThen TeamsPage.cleanUpTeam(tempTeam)
}
}
正如你可以看到我的想法是从一个简单的组合子andThen
这将让我跟进我的测试体与一个副作用。我想通过测试机构的名称,所以它不会开始执行,直到它被包装到Try()
。这是需要的,因为即使在测试主体失败或产生错误的情况下,我也需要后续副作用来执行。 所以我已经声明了一个隐式转换器,它使用by-name参数。 但它不会编译,说我:
Error:(49, 42) type mismatch;
found : Boolean
required: PartialFunction[scala.util.Try[org.scalatest.compatible.Assertion],?]
attempt andThen TeamsPage.cleanUpTeam(tempTeam)
^
我不明白为什么会这样。 如果我改变参数是通过值
object FollowUp{
implicit def assertionToFollowUp(a: Assertion):FollowUp = new FollowUp(a)
}
则代码编译,但它当然不适用的情况下,测试体失败或产生异常的随访。
你能否建议如何以一种很好的方式解决这个问题?
虽然@ephemient解决方案是好的,你可能应该使用它,它看起来像你对你的问题的根本原因感兴趣,但我不能用你的例子重现它。如果我用一些存根填充它的简化版本,它会为我编译(请参阅[完整代码](https://pastebin.com/DdSuS3Tw)我试过了)。那么你能否提供一个[MCVE](https://stackoverflow.com/help/mcve)? – SergGr
明天尝试提取MCVE,虽然它可能不那么容易:) –
我得到了问题所在。我将“andThen”重新命名为“followWith”,然后在两种情况下,当测试主体产生成功的断言和失败时,编译和按预期工作。在思考过错误中提到的“PartialFunction”与我的情况无关之后,我意识到'andThen'是'PartialFunction'的一种方法,所以应该有一些命名阴影或其他东西。所以如果我给这个函数命名,甚至可以使用“alex”。 –