【问题标题】:ScalaTest PlayFrameworkScalaTest PlayFramework
【发布时间】:2016-02-28 11:39:07
【问题描述】:

在学习playframework的同时尝试做一些TDD:

class ContentFetching extends PlaySpec with BeforeAndAfter with MockFactory
{
  private val service = ContentService

  private val languages = List(Language(Some(1), "en", "English", "Placeholder"),
                               Language(Some(2), "de", "Deutsch", "Platzhalter")
                              )

  "find" must
  {
    "fail if languageCode is invalid" in
    {
      val fakeRepository = mock[LanguageRepositoryTrait]
      (fakeRepository.get _).expects().returning(languages)

      fakeRepository.get must have length 3

      service.find("fr") must be Result.NotFound

    }
  }
}

ContentService 会调用:

def fourOhFour() = NotFound(s"Oops, content could not be found")

但断言service.find("fr") must be Result.NotFound 不会编译。为什么会这样以及如何测试呢? 这是整个 contentService(根据要求) 遗憾的是它目前扩展了 Controller,因为我没有找到其他方法来返回 Action。实际上我使用 MVC,但也使用服务 + 存储库层:

class ContentServiceComponent(languageRepository: LanguageRepositoryTrait, nodeRepository: NodeRepositoryTrait) extends Controller
{
  def find(language: String) = Action
  {
    languageRepository.get().map(l => l.code).contains(language) match
    {
      case true => Ok(s"Homepage for $language")
      case false => fourOhFour()
    }
  }

  def fourOhFour() = NotFound(s"Oops, content could not be found")
}

object ContentService extends ContentServiceComponent(LanguageRepository, NodeRepository)

【问题讨论】:

  • ContentServices 是控制器吗?您能否也发布该类或至少找到方法
  • 它是,虽然我不希望它是,因为它是我为解耦添加的另一层。我添加了课程
  • 编译器打印的错误是什么?

标签: scala playframework tdd playframework-2.4


【解决方案1】:

来自 Play 控制器的 service.find("fr") 返回一个结果

也许您正在将 Result 与 Result.Status 类型进行比较?

你能用play.api.helper吗?

status(of: Future[Result]) = Await.result(of, timeout.duration).header.status

代替

service.find("fr") must be Result.NotFound

试试这样的?

status(service.find("fr")) must be NOT_FOUND

NOT_FOUND 是一个 play.api.http.Status 值,只是映射到标准 HTTP 状态代码 404

【讨论】:

    【解决方案2】:

    find 改为返回 Action 可以返回 Option

    def find(language: String): Option[String] =
      {
        languageRepository.get().map(l => l.code).contains(language) match
        {
          case true => Some(s"Homepage for $language")
          case _ => None
        }
      }
    

    所以你可以在 Controller 中按如下方式处理它:

    def index(language:String) = Action{
    
    ContentService.find(language) match{
      case Some(content) => Ok(content)
      case _ => NotFound(s"Oops, content could not be found")
    }
    

    }

    你可以做这样的测试用例:

    class ContentFetching extends PlaySpec with BeforeAndAfter with MockFactory
    {
    
    
      val languages = List(Language(Some(1), "en", "English",Placeholder"),Language(Some(2), "de", "Deutsch", "Platzhalter")
                                  )
    
    val languagesRepositoryMockHere = new LanguageRepositoryTrait{ 
        override def get =  languages  //I don't  know the implementations
    }
    
      "find" must
      {
        "fail if languageCode is invalid" in
        {
           private val service = new ContentServiceComponent(languagesRepositoryMockHere,nodeRepositoryMockHere)
    
    
          service.find("fr") shouldBe None
    
        }
      }
    }
    

    这没有经过测试,但可以帮助参考。

    干杯。

    【讨论】:

    • 当然可以,但这不是我想要实现的。解决方法很好,我自己几乎找到了一个,但我很想知道为什么它不起作用,我认为它应该能够起作用。
    猜你喜欢
    • 2015-11-21
    • 1970-01-01
    • 2012-05-08
    • 1970-01-01
    • 1970-01-01
    • 2015-11-28
    • 2017-03-22
    • 2017-03-31
    • 2015-04-29
    相关资源
    最近更新 更多