くうと徒然なるままに

モバイルアプリを作りながらバックエンドも作っています。

Mockito で void なメソッドをモックする

Mockito はいいぞ〜

さて、 void なメソッドを mock するにはどうすれば良いのかってのは少しハマったので書いてきます〜

解決方法

doNothing().when(targetMock).targetMethod() 的な感じで実装してくといけました〜。

コードで解説

val keyword = "hello world"
doNothing().`when`(target).hoge(keyword)
target.hoge(keyword)
verify(target, times(1)).hoge(keyword)

Android の Fuel + Moshi + Kotlin Coroutine でいい感じにする拡張関数を書いた

Fuel には、 mochi、 Kotlin Coroutine といい感じに連携してくれる機能があります。 けど、 Moshiと Kotlin Coroutine を組み合わせていい感じに呼び出せる関数は存在してないです。(まぁ、標準で存在してても依存関係考えたら載せるべきでないのはそう)(存在してたら教えて!書き換えるから!)

とはいえ、冗長な感じで書いてくのも大変なのでいい感じに移植してきます。

コード

import com.github.kittinunf.fuel.core.FuelError
import com.github.kittinunf.fuel.core.Request
import com.github.kittinunf.fuel.core.Response
import com.github.kittinunf.fuel.core.response
import com.github.kittinunf.fuel.moshi.moshiDeserializerOf
import com.github.kittinunf.result.Result
import kotlinx.coroutines.experimental.Deferred
import kotlinx.coroutines.experimental.GlobalScope
import kotlinx.coroutines.experimental.async

// Response が欲しいとき
inline fun <reified T : Any> Request.awaitResponseObject(): Deferred<Triple<Request, Response, Result<T, FuelError>>> {
  val request = this
  return GlobalScope.async {
    return@async request.response(moshiDeserializerOf<T>())
  }
}

// Result だけが欲しいとき
inline fun <reified T : Any> Request.awaitResultObject(): Deferred<Result<T,FuelError>> {
  val request = this
  return GlobalScope.async {
    return@async request.response(moshiDeserializerOf<T>()).third
  }
}

Request への拡張関数として書きました。
Moshi を使ってシリアライズするやつを Async で非同期に取得するようにしてるだけですね。

java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/databinding/DataBinderMapperImpl; ってエラーがでた

エラーメッセージ

java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/databinding/DataBinderMapperImpl;

解決策

dataBinding {
        enabled = true
}

databinding の設定を AppModule にし忘れてただけですね.... マルチモジュールで作ってると忘れがちなのでメモ...

Invoke-customs are only supported starting with android 0 --min-api 26 ってエラーがでた

ライブラリの追加をしたら下記のようなエラーが出ました。 そこで、解決策を書いていきたいと思います。

Invoke-customs are only supported starting with android 0 --min-api 26

解決策

以下を追加した Module の Build.gradle へ追記したら解決しました。

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

軽く解説

追加した、ライブラリが Android でサポートされていない Java 8 の機能を使っていたからかと思います。

具体的には、Android のアプリを作成する上で 古いAndroid OS では Java 8 の言語機能全てを使うことはできません。
しかし、最新版の Android Studio なら一部使うことができます。

具体的には エラーメッセージにあるように Android 0reo から使うことができるようです。

そのためには、API の最小バージョンを Android Oreo に設定する必要があります。
しかし、現実的に Android O 以下のシェアも以前高いままなため切ることができません。

解決策の中で追加した文字列は、 Androdi アプリのなかで Java 8 の言語機能を使えるようにするためのものです。

実は、上記記述だけではなく 新しめな Android Studio でない場合は 最近の Android Studio で採用されている Build Tool chain を使うように追加で設定する必要ががあるのですが、 いまだに古い Android Studio 使ってる人は解決できるっしょ(新しいの使ってるから調べたくない...) とかあって書いてません。

参考元

stackoverflow.com

developer.android.com

Firebase SDK on Nodejs で Firebase App named '[DEFAULT]' already exists (app/duplicate-app).' ってでた。

Firebase SDK を利用して Nodejs で適当なアプリを書いてたら以下のようなエラーが出ました。

エラーメッセージ

Exception: Worker was unable to load function uploadMeetupListToFirebase: '[DEFAULT]: Firebase: Firebase App named '[DEFAULT]' already exists (app/duplicate-app).'

解決方法

Firebase を初期化するコードを複数回読んでるのが問題らしいです。

firebase.initializeApp(firebaseConfig)

ので、シングルトン的な感じでFirebase クライアントを使いまわすことで解決。

#エンジニア女子だけどフォロワー伸びてない ってタグで一番バズったツイートをした

8RT, 40 Fav でタグの中では一番バズってる

f:id:kuxumarin:20181004013118p:plain

要因

猫パワー

新しいアイコンに変えた, Twitter, Slack, Line とかに使う

某社のずんださんに新しいアイコンを書いてもらいました。

流れ

ずんださんがやるぞ宣言で おえかき宣言 をしていました。

私は、便乗して マグロの中とろ を書いてもらいました。

文句言いながら書いてくれるずんだプロ最高✨

書いてもらった

プロフにした

f:id:kuxumarin:20181003164834j:plain

まとめ

Thank you for Zunda-san!!