import com.google.inject.AbstractModule
class ReservationService@Inject()(
val config: ReservationConfig,
val rule: IReservationRule,
val logic: IReservationLogic,
val factory: IReservationFactory,
val repository: IReservationRepository,
val receptor: IReservationReceptor
) extends IReservationService, IReservationManagement, IReservationAdmin,
IReservationMetrix, EventListener {
…
ReservationService.scala
68.
import com.google.inject.AbstractModule
class ReservationServiceModule(config:Config) extends AbstractModule {
override def configure(): Unit = {
val c = ReservationConfig.create(config)
bind(classOf[IReservationRule]).toInstance(ReservationRule.create(c))
bind(classOf[IReservationLogic]).toInstance(ReservationLogic.create(c))
bind(classOf[IReservationFactory]).toInstance(ReservationFactory.create(c))
bind(classOf[IReservationRepository]).toInstance(ReservationRepository.create(c))
bind(classOf[IReservationReceptor]).toInstance(ReservationReceptor.create(c))
}
}
ReservationServiceModule.scala
class ReservationServiceSpec extendsAnyFreeSpec
with Matchers
with GivenWhenThen
with ReservationMatchers {
"ReservationService" - {
"reserveメソッド" - {
"予約の追加" - {
"現在時刻より後ろの有効な予約時間を予約" in {
Given("テスト⽤に作成したReservationServiceを使⽤")
val service = ReservationService.createForTest()
When("運⽤時間内の時間")
val dt = "2024-01-15T10:00:00+JST"
Then("テスト対象時刻で実⾏コンテキストを⽤意")
given ExecutionContext = ExecutionContext.createWithCurrentDateTime(dt)
And("現在時刻より後ろの有効な予約時間で予約")
ReservationServiceSpec.sbt (1/2)
83.
val rid =ResourceId("id1234")
val uid = UserId("user789")
val start = LocalDateTime.of(2024, 1, 15, 11, 00)
val end = LocalDateTime.of(2024, 1, 15, 12, 00)
val interval = Interval.openUpper(start, end)
val cmd = ReserveCommand(rid, uid, interval)
service.reserve(cmd) should successReserve(cmd)
}
}
}
}
}
ReservationServiceSpec.sbt (2/2)
84.
trait ReservationMatchers {
importReservationMatchers.*
def successReserve(cmd: ReserveCommand): SuccessReserveMatcher =
SuccessReserveMatcher(cmd)
}
object ReservationMatchers {
case class SuccessReserveMatcher(cmd: ReserveCommand)
extends Matcher[Try[ReserveResult]] {
def apply(p: Try[ReserveResult]): MatchResult = {
val result = ???
MatchResult(result, "failure", "success")
}
}
}
ReservationMatcher.scala
85.
sbt:reservation> test
[info] compiling2 Scala sources to
/Users/asami/src/Project2023/ofad/domain/target/scala-3.1.1/test-classes ...
[info] done compiling
[info] ReservationServiceSpec:
[info] ReservationService
[info] reserveメソッド
[info] 予約の追加
[info] - 現在時刻より後ろの有効な予約時間を予約
[info] + Given テスト⽤に作成したReservationServiceを使⽤
[info] + When 運⽤時間内の時間
[info] + Then テスト対象時刻で実⾏コンテキストを⽤意
[info] + And 現在時刻より後ろの有効な予約時間で予約
[info] Run completed in 270 milliseconds.
[info] Total number of tests run: 1
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
[success] Total time: 1 s, completed 2024/01/16 16:00:27
テストを実⾏
86.
class FractionSpec extendsAnyFreeSpec
with Matchers
with GivenWhenThen
with ScalaCheckDrivenPropertyChecks {
case class Fraction(n: Int, d: Int) {
require (d != 0)
require (n != Integer.MIN_VALUE)
require (d != Integer.MIN_VALUE)
val numerator = n * (if (d < 0) -1 else 1)
val denominator = d.abs
}
FractionSpec.scala (1/2)
87.
"分数(例題として)" - {
"分⼦と分⺟の値域の全範囲でnumeratorメソッドとdenominatorメソッドを確認"in {
forAll { (分⼦: Int, 分⺟: Int) =>
whenever (分⺟ != 0 && 分⺟ != Integer.MIN_VALUE && 分⼦ !=
Integer.MIN_VALUE) {
val 分数 = Fraction(分⼦, 分⺟)
if (分⼦ < 0 && 分⺟ < 0 || 分⼦ > 0 && 分⺟ > 0)
分数.numerator should be > 0
else if (分⼦ != 0)
分数.numerator should be < 0
else
分数.numerator should equal (0)
分数.denominator should be > 0
}
}
}
}
}
FractionSpec.scala (2/2)
88.
sbt:reservation> test
[info] compiling2 Scala sources to
/Users/asami/src/Project2023/ofad/domain/target/scala-3.1.1/test-classes ...
[info] done compiling
[info] [info] FractionSpec:
[info] 分数(例題として)
[info] - 分⼦と分⺟の値域の全範囲でnumeratorメソッドとdenominatorメソッドを確認
[info] Run completed in 270 milliseconds.
[info] Total number of tests run: 1
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
[success] Total time: 1 s, completed 2024/01/16 16:00:27
テストを実⾏
参考⽂献
• The UnifiedModeling Language Reference
Manual, 2nd (Rumbaugh他, 2004)
• The Unified Modeling Language User Guide,
2nd (Booch他, 2004)
• The Unified Software Development Process
(Jacobson他, 1999)
• The Object Constraint Language, 2nd (Warmer
他, 2003)
• UML 2 and the Unified Process: Practical
Object-Oriented Analysis and Design (Arlow
他, 2005)
• OMG Unified Modeling Language Version 2.5
(OMG, 2015)
• 上流⼯程UMLモデリング (浅海, 2008)
• Modern Software Engineering : Doing What
Works to Build Better Software Faster (Farley,
2021)