首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >避免在测试文件中实例化对象

避免在测试文件中实例化对象
EN

Stack Overflow用户
提问于 2022-03-29 08:16:00
回答 1查看 60关注 0票数 0

我有一个Redis PubSub对象:

代码语言:javascript
复制
object RedisPubSubService {
  implicit val system = ActorSystem("RedisEtatyLib")

  val config = ConfigFactory.load.getObject("redis").toConfig
  val hostname = config.getString("master")
  val port = config.getInt("port")
  val client = RedisClient(hostname, port)

  val address: InetSocketAddress = new InetSocketAddress(hostname, port)
  val channels = Seq("DASHBOARDS")
  val patterns = Seq("pattern.*")
  var callback: Boolean => Unit = { m => }

  val subscriber = system.actorOf(Props(classOf[SubscribeActor], address, channels, patterns, callback)
    .withDispatcher("rediscala.rediscala-client-worker-dispatcher")
  )

  def publish(channel: String, msg: String) =
     client.publish(channel, msg)
}

class SubscribeActor(address: InetSocketAddress,
                     channels: Seq[String] = Nil,
                     patterns: Seq[String] = Nil,
                     callback: Boolean => Unit)
  extends RedisSubscriberActor(address, channels, patterns, Option(""), callback) {

  def onMessage(message: Message): Unit = {
    // stuff
  }
}

问题是,在Jenkins中运行测试时,不需要实例化这个对象。因此,我的测试失败了,因为我试图连接到本地主机上使用的redis服务器(在application.conf中设置)。我只想在我的测试中忽略这个对象,因为无论如何,我不使用它。

如何在测试文件中实例化应用程序:

代码语言:javascript
复制
val app = new GuiceApplicationBuilder().disable[StartUpService].build()

其中StartUpService是一个单例类。但是对于对象,我不能以这种方式禁用它。

[37 minfo0m p.a.i.l.c.CoordinatedShutdownSupport -使用ServerStoppedReason原因启动同步协调关闭并超时2147533000毫秒] [[37minfo0m p.c.s.AkkaHttpServer -终止/0.0.0.0:9001服务器绑定][37 minfo0m p.c.s.AkkaHttpServer -运行提供的关机停止挂钩连接命令失败,cause = stop (java.net.ConnectException:连接超时)]

thx

基于@Tim,我发现module类实例化了应用程序中的某个对象

代码语言:javascript
复制
class Module extends AbstractModule {
  override def configure() = {
    bind(classOf[StartUpService]).asEagerSingleton
    bind(classOf[TraitRepository]).to(classOf[ClassRepository])
  }
}

由于StartUpService类,我实例化了许多服务,所有这些都是在构建应用程序对象的所有测试中触发的。解决方案是创建一个TestModule (没有StartUp类),并使用它覆盖第一个。

代码语言:javascript
复制
object TestModule extends AbstractModule {
  override def configure() = {
    bind(classOf[TraitRepository]).to(classOf[ClassRepository])
  }
}

现在,我可以在不触发所有服务的情况下创建app对象,如下所示:

代码语言:javascript
复制
val app = new GuiceApplicationBuilder()
        .disable[Module]
        .overrides(TestModule)
        .build()
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-03-29 08:40:22

只有在访问object的成员时才初始化object,因此您必须在测试中使用RedisPubSubService中的至少一个值。

干净的解决方案是将测试中使用的所有值移动到一个单独的类(RedisPubSubConfig?)并且只有RedisPubSubService中的真正服务代码。这样,只有在使用服务时才会创建服务。

测试可以使用单独的object (RedisPubSubMock?)中的模拟服务。也使用RedisPubSubConfig。此object中的代码将仅在测试期间初始化。

或者,您可以制作相关的vals lazy,因此它们只有在首次使用时才会不受重视。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71658636

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档