模拟游戏中的物体[2.0]



我想通过在测试期间提供mock对象来测试我的Play应用程序。在我的脑海中,有几种方法可以解决这个问题。

  1. 在测试期间提供替代路由文件
  2. 使用依赖项注入,并在运行时检查全局值

我不确定哪一个更可行,也不知道如何去做。如有任何见解,我们将不胜感激。

还有第三种方法;将控制器创建为类或特性以进行测试。这里有一个简单的例子。

你的特质+实施:

package services
trait MyService {
  def getUser(id:String):User
}
class ConcreteService extends MyService {
  override def getUser(id:String):User = {
  //Do real stuff
  }
}

在您的控制器类中:

package controllers
import services._
class Users(service: MyService) extends Controller {
  def show(id: String) = Action {
    val user = service.getUser(id)
    Ok(views.html.user(user))
  }
}
object Users extends controllers.Users(new ConcreteService()) {}

现在您可以运行一些单元测试了。。

package test
import controllers.Users
import play.api.test._
import play.api.test.Helpers._
import org.specs2.mock.Mockito
import org.specs2.mutable.Specification
class UsersSpec extends Specification with Mockito {
  val service = mock[MyService]
  "Users controller" should {
    "list users" in {
      //Insert mocking stuff here
      val users = new Users(service)
      val result = users.show("somerandomid")(FakeRequest())
      status(result) must equalTo(OK)
    }
  }
}

我也有同样的问题,并尝试了一些选项:

  • 饼状花纹
  • 通过隐式注入
  • 弹簧

你可以在这里看到github上的代码。

我的解决方案与Blake的类似,只是我在没有控制器作为类的情况下完成了它。你可以在这里查看来源。

为了参考,我添加了一个使用Play插件框架在测试期间注入模拟对象的示例。

  1. http://www.underflow.ca/blog/935/mock-dependency-injection-in-play-2-0

使用这种方法可以在测试时提供一个模拟插件:

class Test extends Specification {
    "application" should {
        "load mock dependency" in {
            running(TestServer(9000, FakeApplication(
            // The plugin at this class replaces the default
            additionalPlugins = Seq("test.MockInjector")
            )), HTMLUNIT) { browser =>
                browser.goTo("http://localhost:9000")
                // Test mock controller
            }
        }
    }
}

MockInjector可用于提供控制器对象或任何其他可注射组件。

注意:我写了博客条目,任何人都可以自由地将博客中的任何和所有内容迁移到这里。

最新更新