我想簡化我的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」。 –