当前位置: 首页 > news >正文

广州做公司网站网站开发培训机构

广州做公司网站,网站开发培训机构,网络直播平台,展示型网站与营销型网站区别翻译自 https://medium.com/mindorks/how-to-unit-test-private-methods-in-java-and-kotlin-d3cae49dccd ❓如何单元测试 Kotlin/Java 中的 private 方法❓ 首先#xff0c;开发者应该测试代码里的 private 私有方法吗#xff1f; 直接信任这些私有方法#xff0c;测试到… 翻译自 https://medium.com/mindorks/how-to-unit-test-private-methods-in-java-and-kotlin-d3cae49dccd ❓如何单元测试 Kotlin/Java 中的 private 方法❓ 首先开发者应该测试代码里的 private 私有方法吗 直接信任这些私有方法测试到调用它们的公开方法感觉就够了吧。 对于这个争论每个开发者都会有自己的观点。 但回到开头的问题本身到底有没有一种合适的途径来实现私有方法的单元测试 截止到目前在面对单元测试私有方法的问题时一般有如下几种选择 不去测试私有方法 *选择信任直接躺平* 将目标方法临时改成 public 公开访问权限 可我不愿意这样做这不符合代码规范。作为一名开发者我要遵循最佳实践 使用嵌套的测试类 *将测试代码和生产代码混到一起不太好吧我再强调一遍我是很优秀的开发者要遵循最佳实践* 使用 Java 反射机制 *听起来还行可以试试这个方案* 大家都知道通过 Java 反射机制可以访问到其他类中的私有属性和方法而且写起来也不麻烦在单元测试里采用该机制应该也很容易上手。 注意 只有将代码作为独立的 Java 程序运行时这个方案才适用就像单元测试、常规的 Java 应用程序。但如果在 Java Applet 上执行反射则需要对 SecurityManager 做些干预。由于这不是高频场景本文不对其作额外阐述。 Java 8 中添加了对反射方法参数的支持使得开发者可以在运行时获得参数名称。 访问私有属性 Class 类提供的 getField(String name) 和 getFields() 只能返回公开访问权限的属性访问私有权限的属性则需要调用 getDeclaredField(String name) 或 getDeclaredFields()。 下面是一个简单的代码示例一个拥有私有属性的类以及如何通过 Java 反射来访问这个属性。 public class PrivateObject {private String privateString null;public PrivateObject(String privateString) {this.privateString privateString;} }PrivateObject privateObject new PrivateObject(The Private Value); Field privateStringField PrivateObject.class.getDeclaredField(privateString);privateStringField.setAccessible(true);String fieldValue (String) privateStringField.get(privateObject);System.out.println(fieldValue fieldValue);上述代码将打印出如下结果内容来自于 PrivateObject 实例的私有属性 privateString 的值。 fieldValue The Private Value需要留意的是getDeclaredField(privateString) 能返回私有属性没错但其范围仅限 class 本身不包含其父类中定义的属性。 还有一点是需要调用 Field.setAcessible(true)目的在于关闭反射里该 Field 的访问检查。 这样的话如果访问的属性是私有的、受保护的或者包可见的即使调用者不满足访问条件仍然可以在反射里获取到该属性。当然非反射的正常代码里依然无法获取到该属性不受影响。 访问私有方法 和访问私有属性一样访问私有方法需要调用 Class 类提供的 getDeclaredMethod(String name, Class[] parameterTypes) 或 Class.getDeclaredMethods()。 同样的我们展示一段代码示例定义了私有方法的类以及通过反射访问它。 public class PrivateObject {private String privateString null;public PrivateObject(String privateString) {this.privateString privateString;}private String getPrivateString(){return this.privateString;} }PrivateObject privateObject new PrivateObject(The Private Value); Method privateStringMethod PrivateObject.class.getDeclaredMethod(getPrivateString, null);privateStringMethod.setAccessible(true);String returnValue (String) privateStringMethod.invoke(privateObject, null);System.out.println(returnValue returnValue);打印出的结果来自于 PrivateObject 实例中私有方法 getPrivateString() 的调用结果。 returnValue The Private Value注意点和访问私有属性一样 getDeclaredMethod() 存在 class 本身的范围限制不能获取到父类中定义的任何方法需要调用 Method.setAcessible(true) 来关闭反射中的 Method 的访问权限检查确保即便不满足访问条件亦能在反射中成功访问 了解完通过反射来访问私有属性、方法的知识之后让我们用在 unit test 中来测试本来难以覆盖到的私有方法。 LoginPresenter.kt 比如我们的代码库中存在如下类 LoginPresenter并且咱们想要去单元测试其私有方法 saveAccount()。 class LoginPresenter Inject constructor(private val view: LoginView,private val strategy: CancelStrategy,private val navigator: AuthenticationNavigator,private val tokenRepository: TokenRepository,private val localRepository: LocalRepository,private val settingsInteractor: GetSettingsInteractor,private val analyticsManager: AnalyticsManager,private val saveCurrentServer: SaveCurrentServerInteractor,private val saveAccountInteractor: SaveAccountInteractor,private val factory: RocketChatClientFactory,val serverInteractor: GetConnectingServerInteractor ) {private var currentServer serverInteractor.get() ?: defaultTestServerprivate val token tokenRepository.get(currentServer)private lateinit var client: RocketChatClientprivate lateinit var settings: PublicSettingsfun setupView() {setupConnectionInfo(currentServer)setupForgotPasswordView()}private fun setupConnectionInfo(serverUrl: String) {currentServer serverUrlclient factory.get(currentServer)settings settingsInteractor.get(currentServer)}private fun setupForgotPasswordView() {if (settings.isPasswordResetEnabled()) {view.showForgotPasswordView()}}fun authenticateWithUserAndPassword(usernameOrEmail: String, password: String) {launchUI(strategy) {view.showLoading()try {val token retryIO(login) {when {settings.isLdapAuthenticationEnabled() -client.loginWithLdap(usernameOrEmail, password)usernameOrEmail.isEmail() -client.loginWithEmail(usernameOrEmail, password)else -client.login(usernameOrEmail, password)}}val myself retryIO(me()) { client.me() }myself.username?.let { username -val user User(id myself.id,roles myself.roles,status myself.status,name myself.name,emails myself.emails?.map { Email(it.address ?: , it.verified) },username username,utcOffset myself.utcOffset)localRepository.saveCurrentUser(currentServer, user)saveCurrentServer.save(currentServer)localRepository.save(LocalRepository.CURRENT_USERNAME_KEY, username)saveAccount(username)saveToken(token)analyticsManager.logLogin(AuthenticationEvent.AuthenticationWithUserAndPassword,true)view.saveSmartLockCredentials(usernameOrEmail, password)navigator.toChatList()}} catch (exception: RocketChatException) {when (exception) {is RocketChatTwoFactorException - {navigator.toTwoFA(usernameOrEmail, password)}else - {analyticsManager.logLogin(AuthenticationEvent.AuthenticationWithUserAndPassword,false)exception.message?.let {view.showMessage(it)}.ifNull {view.showGenericErrorMessage()}}}} finally {view.hideLoading()}}}fun forgotPassword() navigator.toForgotPassword()private fun saveAccount(username: String) {val icon settings.favicon()?.let {currentServer.serverLogoUrl(it)}val logo settings.wideTile()?.let {currentServer.serverLogoUrl(it)}val thumb currentServer.avatarUrl(username, token?.userId, token?.authToken)val account Account(settings.siteName() ?: currentServer,currentServer,icon,logo,username,thumb)saveAccountInteractor.save(account)}private fun saveToken(token: Token) tokenRepository.save(currentServer, token) }LoginPresenterTest.kt 单元测试的整体如下 class LoginPresenterTest {private val view mock(LoginView::class.java)private val strategy mock(CancelStrategy::class.java)private val navigator mock(AuthenticationNavigator::class.java)private val tokenRepository mock(TokenRepository::class.java)private val localRepository mock(LocalRepository::class.java)private val settingsInteractor mock(GetSettingsInteractor::class.java)private val analyticsManager mock(AnalyticsManager::class.java)private val saveCurrentServer mock(SaveCurrentServerInteractor::class.java)private val saveAccountInteractor mock(SaveAccountInteractor::class.java)private val factory mock(RocketChatClientFactory::class.java)private val serverInteractor mock(GetConnectingServerInteractor::class.java)private val token mock(Token::class.java)const val currentServer: String https://open.rocket.chatconst val USERNAME: String user121const val PASSWORD: String 123456lateinit var loginPresenter: LoginPresenterprivate val account Account(currentServer, currentServer, null,null, USERNAME, UPDATED_AVATAR)Beforefun setUp() {MockitoAnnotations.initMocks(this)when(strategy.isTest).thenReturn(true)when(serverInteractor.get()).thenReturn(currentServer)loginPresenter LoginPresenter(view, strategy, navigator, tokenRepository, localRepository, settingsInteractor,analyticsManager, saveCurrentServer, saveAccountInteractor, factory, serverInteractor)}Testfun check account is saved() {...} }通过反射机制私有方法 saveAccount() 的单测则可以很方便地进行。 class LoginPresenterTest {...Testfun check account is saved() {loginPresenter.setupView()val method loginPresenter.javaClass.getDeclaredMethod(saveAccount, String::class.java)method.isAccessible trueval parameters arrayOfNullsAny(1)parameters[0] USERNAMEmethod.invoke(loginPresenter, *parameters)verify(saveAccountInteractor).save(account)} }本文浅显易懂希望能向你展示反射的魔力帮助开发者在单元测试中优雅、便捷地 cover 到私有方法 最后感谢你的阅读。
http://www.w-s-a.com/news/583667/

相关文章:

  • 网站建设与维护 课件网页版qq安全中心登录入口
  • 做三个月网站广告收入dw如何制作网页
  • ...课程网站建设简介工信部 网站备案查询
  • 网站代码建设 实例企业网站建设大概的费用
  • 制作网站软件排行榜过年做啥网站致富
  • 哪里有做网站企业seo关键词优化
  • 上海金山网站建设公司手机淘宝客网站怎么做的
  • 网站开发需要公司做网站费用计入什么科目
  • 网站优化有哪些类型免费制作app的傻瓜软件
  • 如何做网站咨询wordpress get
  • 企业网站建设网站做网站用别人的图片
  • 站长统计代码个人网站源代码
  • 求推荐专门做借条的网站公众号排版编辑器
  • 动态做网站网站开发语言查询 蔡学镛
  • 莆田网站建设创意自助建站英文
  • cms系统创建静态网站龙岗网站建设哪家好
  • 自己做的网站被封了邢台规划局网站建设
  • 网站建设项目合同wordpress主题没法用
  • 个旧市哪里有做网站wordpress内页php页面
  • 程序员接活的平台网站互联网平台建设方案
  • 网站安全建设模板深圳企业管理咨询公司
  • 做网站 还是淘宝店wordpress分类链接后加
  • wordpress腾讯云 COSseo内容优化心得
  • 特价旅游机票网站建设i营销
  • 如何成立网站深圳创业项目
  • 建设商业网站惠州网站建设推荐乐云seo
  • 如何申请免费域名做网站免费推广神器
  • 自媒体人专用网站安岳网站建设
  • 特乐网站建设做网站推广要多少钱
  • 山东省建设安全生产协会网站义乌跨境电商公司前十名