如何在蛋糕图案上使用模拟 [英] How to use mocks with the Cake Pattern

查看:93
本文介绍了如何在蛋糕图案上使用模拟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下课程:

class LinkUserService() {

  //** cake pattern **
  oauthProvider: OAuthProvider =>
  //******************

  def isUserLinked(userId: String, service: String) = {
    val cred = oauthProvider.loadCredential(userId)
    cred != null

  }

  def linkUserAccount(userId: String, service: String): (String, Option[String]) = {
    if (isUserLinked(userId, service)) {
      ("SERVICE_LINKED", None)
    } else {
      val authUrl = oauthProvider.newAuthorizationUrl
      ("SERVICE_NOT_LINKED", Some(authUrl))
    }
  }

  def setLinkAuthToken(userId: String, service:String, token:String):String = {
    oauthProvider.createAndStoreCredential(userId, token)
  }

}

通常,我会在生产中使用此类,例如:

Typically I'd use this class in production like so:

val linkService = LinkUserService with GoogleOAuthProvider

在测试方面,我想用一个模拟代替oauthProvider,该模拟已经由我的单元测试训练过,可以像这样响应:oauthProvider.loadCredential("nobody") returns null.这可能吗?如果是这样,我将如何设置我的单元测试?

When it comes to testing, I want to replace the oauthProvider with a mock such that's been trained by my unit test to respond like so: oauthProvider.loadCredential("nobody") returns null. Is this possible? If so, how would I set up my unit test to do so?

推荐答案

您遇到了此问题,因为您没有完全使用蛋糕模式.如果你写类似

You have this problem because you are not using cake pattern to full extent. If you write something like

trait LinkUserServiceComponent {
    this: OAuthProviderComponent =>

    val linkUserService = new LinkUserService

    class LinkUserService {
        // use oauthProvider explicitly
        ...
    }
}

trait GoogleOAuthProviderComponent {
    val oauthProvider = new GoogleOAuthProvider

    class GoogleOAuthProvider {
        ...
    }
}

然后使用这样的模拟程序:

And then you use a mock like this:

val combinedComponent = new LinkUserServiceComponent with OAuthProviderComponent {
    override val oauthProvider = mock(...)
}

然后您的问题消失了.如果您还使通用接口特性像这样(并使其他组件依赖于接口,而不依赖于实现):

Then your problem disappears. If you also make generic interface traits like this (and make other components depend on interface, not on implementation):

trait OAuthProviderComponent {
    def oauthProvider: OAuthProvider

    trait OAuthProvider {
        // Interface declaration
    }
}

然后,您还将拥有通用的可重用和可测试的代码.

then you also would have generic reusable and testable code.

这与您的建议非常相似,确实是蛋糕图案的本质.

This is very similar to your suggestion and it really is the essence of cake pattern.

这篇关于如何在蛋糕图案上使用模拟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆