This commit is contained in:
Jonathan Cook
2019-10-23 15:01:44 +02:00
parent db85c8f275
commit 684ec0d2e3
20486 changed files with 1642483 additions and 0 deletions
+14
View File
@@ -0,0 +1,14 @@
/bin/
#ignore gradle
.gradle/
#ignore build and generated files
build/
node/
out/
#ignore installed node modules and package lock file
node_modules/
package-lock.json
+11
View File
@@ -0,0 +1,11 @@
## Kotlin Libraries
This module contains articles about Kotlin Libraries.
### Relevant articles:
- [Jackson Support for Kotlin](https://www.baeldung.com/jackson-kotlin)
- [Introduction to RxKotlin](https://www.baeldung.com/rxkotlin)
- [MockK: A Mocking Library for Kotlin](https://www.baeldung.com/kotlin-mockk)
- [Kotlin Immutable Collections](https://www.baeldung.com/kotlin-immutable-collections)
- More articles: [[<-- prev]](/kotlin-libraries)
+57
View File
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>kotlin-libraries-2</artifactId>
<name>kotlin-libraries-2</name>
<packaging>jar</packaging>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-kotlin</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../parent-kotlin</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
</dependency>
<dependency>
<groupId>io.reactivex.rxjava2</groupId>
<artifactId>rxkotlin</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jetbrains.kotlinx/kotlinx-collections-immutable -->
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-collections-immutable</artifactId>
<version>${kotlinx-collections-immutable.version}</version>
</dependency>
<!-- MockK dependencies-->
<dependency>
<groupId>io.mockk</groupId>
<artifactId>mockk</artifactId>
<version>${mockk.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<guava.version>27.1-jre</guava.version>
<mockk.version>1.9.3</mockk.version>
<kotlinx-collections-immutable.version>0.1</kotlinx-collections-immutable.version>
</properties>
</project>
+11
View File
@@ -0,0 +1,11 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
@@ -0,0 +1,8 @@
package com.baeldung.kotlin.jackson
import com.fasterxml.jackson.annotation.*
@JsonInclude(JsonInclude.Include.NON_EMPTY)
data class Book(var title: String, @JsonProperty("author") var authorName: String) {
var genres: List<String>? = emptyList()
}
@@ -0,0 +1,3 @@
package com.baeldung.kotlin.jackson
data class Movie(var name: String, var studio: String, var rating: Float? = 1f)
@@ -0,0 +1,27 @@
package com.baeldung.kotlin.immutable
import junit.framework.Assert.assertEquals
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.immutableListOf
import org.junit.Rule
import org.junit.Test
import org.junit.rules.ExpectedException
class KotlinxImmutablesUnitTest{
@Rule
@JvmField
var ee : ExpectedException = ExpectedException.none()
@Test
fun givenKICLList_whenAddTried_checkExceptionThrown(){
val list: ImmutableList<String> = immutableListOf("I", "am", "immutable")
list.add("My new item")
assertEquals(listOf("I", "am", "immutable"), list)
}
}
@@ -0,0 +1,73 @@
package com.baeldung.kotlin.immutable
import com.google.common.collect.ImmutableList
import com.google.common.collect.ImmutableSet
import junit.framework.Assert.assertEquals
import org.junit.Rule
import org.junit.Test
import org.junit.rules.ExpectedException
class ReadOnlyUnitTest{
@Test
fun givenReadOnlyList_whenCastToMutableList_checkNewElementsAdded(){
val list: List<String> = listOf("This", "Is", "Totally", "Immutable")
(list as MutableList<String>)[2] = "Not"
assertEquals(listOf("This", "Is", "Not", "Immutable"), list)
}
@Rule
@JvmField
var ee : ExpectedException = ExpectedException.none()
@Test
fun givenImmutableList_whenAddTried_checkExceptionThrown(){
val list: List<String> = ImmutableList.of("I", "am", "actually", "immutable")
ee.expect(UnsupportedOperationException::class.java)
(list as MutableList<String>).add("Oops")
}
@Test
fun givenMutableList_whenCopiedAndAddTried_checkExceptionThrown(){
val mutableList : List<String> = listOf("I", "Am", "Definitely", "Immutable")
(mutableList as MutableList<String>)[2] = "100% Not"
assertEquals(listOf("I", "Am", "100% Not", "Immutable"), mutableList)
val list: List<String> = ImmutableList.copyOf(mutableList)
ee.expect(UnsupportedOperationException::class.java)
(list as MutableList<String>)[2] = "Really?"
}
@Test
fun givenImmutableSetBuilder_whenAddTried_checkExceptionThrown(){
val mutableList : List<String> = listOf("Hello", "Baeldung")
val set: ImmutableSet<String> = ImmutableSet.builder<String>()
.add("I","am","immutable")
.addAll(mutableList)
.build()
assertEquals(setOf("Hello", "Baeldung", "I", "am", "immutable"), set)
ee.expect(UnsupportedOperationException::class.java)
(set as MutableSet<String>).add("Oops")
}
}
@@ -0,0 +1,114 @@
package com.baeldung.kotlin.jackson
import org.junit.Test
import kotlin.test.assertTrue
import kotlin.test.assertFalse
import kotlin.test.assertEquals
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.KotlinModule
class JacksonUnitTest {
//val mapper = jacksonObjectMapper()
val mapper = ObjectMapper().registerModule(KotlinModule())
@Test
fun whenSerializeMovie_thenSuccess() {
val movie = Movie("Endgame", "Marvel", 9.2f)
val serialized = mapper.writeValueAsString(movie)
val json = """{"name":"Endgame","studio":"Marvel","rating":9.2}"""
assertEquals(serialized, json)
}
@Test
fun whenDeserializeMovie_thenSuccess() {
val json = """{"name":"Endgame","studio":"Marvel","rating":9.2}"""
// val movie: Movie = mapper.readValue(json)
val movie = mapper.readValue<Movie>(json)
assertEquals(movie.name, "Endgame")
assertEquals(movie.studio, "Marvel")
assertEquals(movie.rating, 9.2f)
}
@Test
fun whenDeserializeMovieWithMissingValue_thenUseDefaultValue() {
val json = """{"name":"Endgame","studio":"Marvel"}"""
val movie: Movie = mapper.readValue(json)
assertEquals(movie.name, "Endgame")
assertEquals(movie.studio, "Marvel")
assertEquals(movie.rating, 1f)
}
@Test
fun whenSerializeMap_thenSuccess() {
val map = mapOf(1 to "one", 2 to "two")
val serialized = mapper.writeValueAsString(map)
val json = """{"1":"one","2":"two"}"""
assertEquals(serialized, json)
}
@Test
fun whenDeserializeMap_thenSuccess() {
val json = """{"1":"one","2":"two"}"""
val aMap: Map<Int,String> = mapper.readValue(json)
assertEquals(aMap[1], "one")
assertEquals(aMap[2], "two")
}
@Test
fun whenSerializeList_thenSuccess() {
val movie1 = Movie("Endgame", "Marvel", 9.2f)
val movie2 = Movie("Shazam", "Warner Bros", 7.6f)
val movieList = listOf(movie1, movie2)
val serialized = mapper.writeValueAsString(movieList)
val json = """[{"name":"Endgame","studio":"Marvel","rating":9.2},{"name":"Shazam","studio":"Warner Bros","rating":7.6}]"""
assertEquals(serialized, json)
}
@Test
fun whenDeserializeList_thenSuccess() {
val json = """[{"name":"Endgame","studio":"Marvel","rating":9.2},{"name":"Shazam","studio":"Warner Bros","rating":7.6}]"""
val movieList: List<Movie> = mapper.readValue(json)
val movie1 = Movie("Endgame", "Marvel", 9.2f)
val movie2 = Movie("Shazam", "Warner Bros", 7.6f)
assertTrue(movieList.contains(movie1))
assertTrue(movieList.contains(movie2))
}
@Test
fun whenSerializeBook_thenSuccess() {
val book = Book("Oliver Twist", "Charles Dickens")
val serialized = mapper.writeValueAsString(book)
val json = """{"title":"Oliver Twist","author":"Charles Dickens"}"""
assertEquals(serialized, json)
}
@Test
fun whenDeserializeBook_thenSuccess() {
val json = """{"title":"Oliver Twist","author":"Charles Dickens"}"""
val book: Book = mapper.readValue(json)
assertEquals(book.title, "Oliver Twist")
assertEquals(book.authorName, "Charles Dickens")
}
@Test
fun givenJsonInclude_whenSerializeBook_thenEmptyFieldExcluded() {
val book = Book("Oliver Twist", "Charles Dickens")
val serialized = mapper.writeValueAsString(book)
val json = """{"title":"Oliver Twist","author":"Charles Dickens"}"""
assertEquals(serialized, json)
}
}
@@ -0,0 +1,157 @@
package com.baeldung.kotlin.rxkotlin
import io.reactivex.Maybe
import io.reactivex.Observable
import io.reactivex.functions.BiFunction
import io.reactivex.rxkotlin.*
import io.reactivex.subjects.PublishSubject
import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
class RxKotlinTest {
@Test
fun whenBooleanArrayToObserver_thenBooleanObserver() {
val observable = listOf(true, false, false).toObservable()
observable.test().assertValues(true, false, false)
}
@Test
fun whenBooleanArrayToFlowable_thenBooleanFlowable() {
val flowable = listOf(true, false, false).toFlowable()
flowable.buffer(2).test().assertValues(listOf(true, false), listOf(false))
}
@Test
fun whenIntArrayToObserver_thenIntObserver() {
val observable = listOf(1, 1, 2, 3).toObservable()
observable.test().assertValues(1, 1, 2, 3)
}
@Test
fun whenIntArrayToFlowable_thenIntFlowable() {
val flowable = listOf(1, 1, 2, 3).toFlowable()
flowable.buffer(2).test().assertValues(listOf(1, 1), listOf(2, 3))
}
@Test
fun whenObservablePairToMap_thenSingleNoDuplicates() {
val list = listOf(Pair("a", 1), Pair("b", 2), Pair("c", 3), Pair("a", 4))
val observable = list.toObservable()
val map = observable.toMap()
assertEquals(mapOf(Pair("a", 4), Pair("b", 2), Pair("c", 3)), map.blockingGet())
}
@Test
fun whenObservablePairToMap_thenSingleWithDuplicates() {
val list = listOf(Pair("a", 1), Pair("b", 2), Pair("c", 3), Pair("a", 4))
val observable = list.toObservable()
val map = observable.toMultimap()
assertEquals(
mapOf(Pair("a", listOf(1, 4)), Pair("b", listOf(2)), Pair("c", listOf(3))),
map.blockingGet())
}
@Test
fun whenMergeAll_thenStream() {
val subject = PublishSubject.create<Observable<String>>()
val observable = subject.mergeAll()
val testObserver = observable.test()
subject.onNext(Observable.just("first", "second"))
testObserver.assertValues("first", "second")
subject.onNext(Observable.just("third", "fourth"))
subject.onNext(Observable.just("fifth"))
testObserver.assertValues("first", "second", "third", "fourth", "fifth")
}
@Test
fun whenConcatAll_thenStream() {
val subject = PublishSubject.create<Observable<String>>()
val observable = subject.concatAll()
val testObserver = observable.test()
subject.onNext(Observable.just("first", "second"))
testObserver.assertValues("first", "second")
subject.onNext(Observable.just("third", "fourth"))
subject.onNext(Observable.just("fifth"))
testObserver.assertValues("first", "second", "third", "fourth", "fifth")
}
@Test
fun whenSwitchLatest_thenStream() {
val subject = PublishSubject.create<Observable<String>>()
val observable = subject.switchLatest()
val testObserver = observable.test()
subject.onNext(Observable.just("first", "second"))
testObserver.assertValues("first", "second")
subject.onNext(Observable.just("third", "fourth"))
subject.onNext(Observable.just("fifth"))
testObserver.assertValues("first", "second", "third", "fourth", "fifth")
}
@Test
fun whenMergeAllMaybes_thenObservable() {
val subject = PublishSubject.create<Maybe<Int>>()
val observable = subject.mergeAllMaybes()
val testObserver = observable.test()
subject.onNext(Maybe.just(1))
subject.onNext(Maybe.just(2))
subject.onNext(Maybe.empty())
testObserver.assertValues(1, 2)
subject.onNext(Maybe.error(Exception("")))
subject.onNext(Maybe.just(3))
testObserver.assertValues(1, 2).assertError(Exception::class.java)
}
@Test
fun whenMerge_thenStream() {
val observables = mutableListOf(Observable.just("first", "second"))
val observable = observables.merge()
observables.add(Observable.just("third", "fourth"))
observables.add(Observable.error(Exception("e")))
observables.add(Observable.just("fifth"))
observable.test().assertValues("first", "second", "third", "fourth").assertError(Exception::class.java)
}
@Test
fun whenMergeDelayError_thenStream() {
val observables = mutableListOf<Observable<String>>(Observable.error(Exception("e1")))
val observable = observables.mergeDelayError()
observables.add(Observable.just("1", "2"))
observables.add(Observable.error(Exception("e2")))
observables.add(Observable.just("3"))
observable.test().assertValues("1", "2", "3").assertError(Exception::class.java)
}
@Test
fun whenCast_thenUniformType() {
val observable = Observable.just<Number>(1, 1, 2, 3)
observable.cast<Int>().test().assertValues(1, 1, 2, 3)
}
@Test
fun whenOfType_thenFilter() {
val observable = Observable.just(1, "and", 2, "and")
observable.ofType<Int>().test().assertValues(1, 2)
}
@Test
fun whenFunction_thenCompletable() {
var value = 0
val completable = { value = 3 }.toCompletable()
assertFalse(completable.test().isCancelled)
assertEquals(3, value)
}
@Test
fun whenHelper_thenMoreIdiomaticKotlin() {
val zipWith = Observable.just(1).zipWith(Observable.just(2)) { a, b -> a + b }
zipWith.subscribeBy(onNext = { println(it) })
val zip = Observables.zip(Observable.just(1), Observable.just(2)) { a, b -> a + b }
zip.subscribeBy(onNext = { println(it) })
val zipOrig = Observable.zip(Observable.just(1), Observable.just(2), BiFunction<Int, Int, Int> { a, b -> a + b })
zipOrig.subscribeBy(onNext = { println(it) })
}
}
@@ -0,0 +1,44 @@
package com.baeldung.mockk
import io.mockk.MockKAnnotations
import io.mockk.every
import io.mockk.impl.annotations.InjectMockKs
import io.mockk.impl.annotations.MockK
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals
class InjectTestService {
lateinit var service1: TestableService
lateinit var service2: TestableService
fun invokeService1(): String {
return service1.getDataFromDb("Test Param")
}
}
class AnnotationMockKUnitTest {
@MockK
lateinit var service1: TestableService
@MockK
lateinit var service2: TestableService
@InjectMockKs
var objectUnderTest = InjectTestService()
@BeforeEach
fun setUp() = MockKAnnotations.init(this)
@Test
fun givenServiceMock_whenCallingMockedMethod_thenCorrectlyVerified() {
// given
every { service1.getDataFromDb("Test Param") } returns "No"
// when
val result = objectUnderTest.invokeService1()
// then
assertEquals("No", result)
}
}
@@ -0,0 +1,92 @@
package com.baeldung.mockk
import io.mockk.*
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals
class BasicMockKUnitTest {
@Test
fun givenServiceMock_whenCallingMockedMethod_thenCorrectlyVerified() {
// given
val service = mockk<TestableService>()
every { service.getDataFromDb("Expected Param") } returns "Expected Output"
// when
val result = service.getDataFromDb("Expected Param")
// then
verify { service.getDataFromDb("Expected Param") }
assertEquals("Expected Output", result)
}
@Test
fun givenServiceSpy_whenMockingOnlyOneMethod_thenOtherMethodsShouldBehaveAsOriginalObject() {
// given
val service = spyk<TestableService>()
every { service.getDataFromDb(any()) } returns "Mocked Output"
// when checking mocked method
val firstResult = service.getDataFromDb("Any Param")
// then
assertEquals("Mocked Output", firstResult)
// when checking not mocked method
val secondResult = service.doSomethingElse("Any Param")
// then
assertEquals("I don't want to!", secondResult)
}
@Test
fun givenRelaxedMock_whenCallingNotMockedMethod_thenReturnDefaultValue() {
// given
val service = mockk<TestableService>(relaxed = true)
// when
val result = service.getDataFromDb("Any Param")
// then
assertEquals("", result)
}
@Test
fun givenObject_whenMockingIt_thenMockedMethodShouldReturnProperValue() {
// given
val service = TestableService()
mockkObject(service)
// when calling not mocked method
val firstResult = service.getDataFromDb("Any Param")
// then return real response
assertEquals("Value from DB", firstResult)
// when calling mocked method
every { service.getDataFromDb(any()) } returns "Mocked Output"
val secondResult = service.getDataFromDb("Any Param")
// then return mocked response
assertEquals("Mocked Output", secondResult)
}
@Test
fun givenMock_whenCapturingParamValue_thenProperValueShouldBeCaptured() {
// given
val service = mockk<TestableService>()
val slot = slot<String>()
every { service.getDataFromDb(capture(slot)) } returns "Expected Output"
// when
service.getDataFromDb("Expected Param")
// then
assertEquals("Expected Param", slot.captured)
}
@Test
fun givenMock_whenCapturingParamsValues_thenProperValuesShouldBeCaptured() {
// given
val service = mockk<TestableService>()
val list = mutableListOf<String>()
every { service.getDataFromDb(capture(list)) } returns "Expected Output"
// when
service.getDataFromDb("Expected Param 1")
service.getDataFromDb("Expected Param 2")
// then
assertEquals(2, list.size)
assertEquals("Expected Param 1", list[0])
assertEquals("Expected Param 2", list[1])
}
}
@@ -0,0 +1,33 @@
package com.baeldung.mockk
import io.mockk.*
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals
class Foo {
lateinit var name: String
lateinit var bar: Bar
}
class Bar {
lateinit var nickname: String
}
class HierarchicalMockKUnitTest {
@Test
fun givenHierarchicalClass_whenMockingIt_thenReturnProperValue() {
// given
val foo = mockk<Foo> {
every { name } returns "Karol"
every { bar } returns mockk {
every { nickname } returns "Tomato"
}
}
// when
val result = foo.bar.nickname
// then
assertEquals("Tomato", result)
}
}
@@ -0,0 +1,12 @@
package com.baeldung.mockk
class TestableService {
fun getDataFromDb(testParameter: String): String {
// query database and return matching value
return "Value from DB"
}
fun doSomethingElse(testParameter: String): String {
return "I don't want to!"
}
}