Git Product home page Git Product logo

kluent's Introduction

Kluent

Changelog Documentation Contributors Current version

Kluent is a "Fluent Assertions" library written specifically for Kotlin.

It uses the Infix-Notations and Extension Functions of Kotlin to provide a fluent wrapper around the JUnit-Assertions.

How to contribute


Include it via gradle/maven

Kluent is hosted here at mavenCentral

Kluent-Android is hosted here at mavenCentral

Gradle

Replace {version} with the current version and chose one of the two artifacts, based on your target platform:

// Add jcenter as a repository for dependencies
repositories {
    mavenCentral()
}

dependencies {
    // for JVM:
    testImplementation 'org.amshove.kluent:kluent:{version}'

    // for Android:
    testImplementation 'org.amshove.kluent:kluent-android:{version}'

    // To get JUnit errors from kotlin.test, to e.g. enable diff windows in failure messages
    testImplementation "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version"
}

Maven

Replace {version} with the current version

<dependency>
    <groupId>org.amshove.kluent</groupId>
    <artifactId>kluent</artifactId>
    <version>{version}</version>
    <type>pom</type>
</dependency>

Examples

More examples can be seen on the Site or in the tests.

assertEquals

"hello" shouldBeEqualTo "hello"

assertNotEquals

"hello" shouldNotBeEqualTo "world"

Assert that an Array/Iterable contains something

val alice = Person("Alice", "Bob")
val jon = Person("Jon", "Doe")
val list = listOf(alice, jon)
list shouldContain jon

Using backticks

Every method that is included in Kluent also has a "backtick version", to make it feel more like a describing sentence.

Some examples:

assertEquals

"hello" `should be equal to` "hello"

assertNotEquals

"hello" `should not be equal to` "world"

Building Kluent

All projects of Kluent are built with Gradle

The default gradlew build will only build the common and jvm module, to keep the build times as small as possible.

If you plan to submit a pull request, it is also fine if you just make sure it builds and tests against common and jvm (which gradlew build will make sure of), because the rest of the heavy work will be done by Travis and AppVeyor. That way you can keep your machine free from NodeJS and Kotlin Native :-)

To build the Android library, pass the parameter ANDROID to Gradle. This will build the common and android artifacts. To pass the parameter, type:

gradlew build -PANDROID

To also build the JS module, pass JS:

gradlew build -PJS

To build native, pass:

gradlew build -PNATIVE

In these cases, the JVM module will also be built, because it is our primary target and everything should pass on the JVM. To skip the JVM build, e.g. for testing only against Native or JS, pass SKIPVM:

gradlew build -PJS -PNATIVE -PSKIPJVM

This command will build common, js, native, but not jvm.

Where to put new features

If you plan to add a feature (e.g. an Assertion), it would be nice to first try adding it to the common module, as it would then be available to all platforms. If it uses specific APIs, like classes from the Java standard library, then it needs to go to the jvm module.

If you're unsure where to put a feature, or if you want to put something in the common module which needs platform specific implementations, you can have a look here (platformIsDigit or platformClassName) where a function in the common module calls a so called expect function, which is defined here in the common module and has specific JVM , JS and Native implementation.

If you're still unsure how to make something platform independent, we can have a look together inside the PR :-)

Attribution

Parts of the assertSoftly feature are based upon the great work of Kotest under the Apache 2.0 License.

kluent's People

Contributors

adeconinck-zenika avatar amc6 avatar andersu avatar andreasvolkmann avatar cketti avatar drcolombo avatar fabriciorissetto avatar floralvikings avatar gregwoodfill avatar guenhter avatar ivanatanasov89 avatar javatarz avatar jcminarro avatar jcornaz avatar jeggy avatar kshitij09 avatar markusamshove avatar mrobakowski avatar murtaught avatar priyaaank avatar samneirinck avatar samsonjs avatar sheix avatar sschuberth avatar tgirard12 avatar timo-a avatar ursjoss avatar vitusortner avatar vjames19 avatar ychescale9 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kluent's Issues

Number operations

Hi,

I was just writing some tests where I assert that the size of a Collection is not 0, i.e. the Collection is not empty.

persSpecs.size shouldNotBe 0

The error message reads: expected not same.

I kind of miss a shouldBeGreaterThan and shouldBeLessThan.

Can't create 'any' matcher for String or Java interface

Heya, I am attempting to 'any' match a String and an interface from a Java library, but contrary to Double, I can't seem to get them to work. Is there a different approach I should take for non-primitives?

interface Foo {

}

println(Double::class.toString())         // prints "class kotlin.Double" 
println(Double::class.java.toString())    // prints "double"
println(any(Double::class))               // prints "0.0"

println(String::class.toString())         // prints "class kotlin.String"
println(String::class.java.toString())    // prints "class java.lang.String"
println(any(String::class))               // throws "java.lang.IllegalStateException: any(kClass.javaObjectType) must not be null"

println(Foo::class.toString())            // prints "class Foo"
println(Foo::class.java.toString())       // prints "interface Foo"
println(any(Foo::class))                  // throws "java.lang.IllegalStateException: any(kClass.javaObjectType) must not be null"

I'm using Spek 1.1.0-beta4 with Kluent 1.16. The Mockito version that was pulled in is 2.1.0 (explicitly depending on the latest version doesn't seem to change anything).

Thank you

`should throw` doesn't work with functions with parameters

For example, the following will not compile:

val func = { a: Int, b: Int -> a / b }
func(1, 0) `should throw` ArithmeticException::class

I've quickly looked into this, but can't find a solution so far. Looks like there's no way to declare a function type with vararg params, e.g. ((vararg params: Any) -> Any), but this can be solved with providing multiple versions of should throw for functions having from 0 to 9 parameters - this should work for 99.99% cases. However, I can't figure out how to reference the parameters when invoking the function, will keep looking for the solution.

Iterable should contain some

Currently testing some iterables and found that Kluent lacks support for the following:

  1. I have a List which contains some elements that are expected.
  2. I have a List which contains actual elements

2 should contain at least some of 1, but not necessarily all (shouldContainAll).

It's kind of the inverse of shouldNotContainAny.
-> should contain some

val cities = listOf("Israel", "Phoenix", "Egypt")
val actual = listOf("Israel", "Some", "other", "Phoenix") // Egypt is missing

// long version
actual.any { it in cities }.shouldBeTrue()

// fails, not the one i am looking for
actual shouldContainAll cities

// what I propose
actual shouldContainSome cities

File assertions!

I know you have been working on something with File, but when are we getting File.shouldExist() ? ๐Ÿ“

I can supply it.

Use mockito-kotlin-kt1.1

Version 1.5.0 of mockito-kotlin introduced a new artifact for Kotlin 1.1. Since this project already depends on Kotlin 1.1, shouldn't we be using this new artifact?

Can't assert throwables

All exception checking is restricted to Exceptions:

infix fun <T : Exception> (() -> Any).`should throw`(expectedException: KClass<T>) {

Where they need to be less restriced to the superclass of Exception which is Throwable in order to assert any throw statement at all.

infix fun <T : Throwable> (() -> Any).`should throw`(expectedException: KClass<T>) {

Example failing (to compile) usecases:

@Test
fun `should throw uncompilable example`() {
    {
        1 `should be` 2
    } `should throw` AssertionError::class
}

@Test
fun `pure example of should throw uncompilable`() {
    {
        throw Throwable()
    } `should throw` Throwable::class
}

But this is fine:

@Test(expected = AssertionError::class)
fun `assertion error (throwable) example`() {
        1 `should be` 2
}

@Test(expected = Throwable::class)
fun `pure throwable example`() {
    throw Throwable()
}

Assert equals is not working for ByteArray

I was trying to compare if two ByteArray content is equal and saw following message:

java.lang.AssertionError: 
Expected :[B@4926097b
Actual   :[B@762efe5d

But when I use Arrays.equal() or assertArrayEqual() test is green.

To reproduce it add following code in test case:

val testArray = byteArrayOf(1, 3, 4, 12)
testArray.copyOf() `should equal` testArray

My suspicion is that for other similar arrays it will also not work.

Include actual exception when `shouldThrowTheException` fails

Actual situation

When a should throw the exception fails, the message states:

Expected foo.bar.TheExpectedException to be thrown expected:<class [foo.bar.TheExpected]Exception> but was:<class [kotlin.KotlinNullPointer]Exception>

Then I can see the stack trace of that ComparisonFailure (at least, in the IDE).

Problem

That indicates only the point of failure in the test (the assertion itself), but does not give me any information about the exception that did occur in reality (that was not expected). I need then to trace and/or modify temporarily my test code so it just fails (remove the assertion) and then I can see what happened.

Proposition

Include the actual exception as a cause of the thrown ComparisonFailure. That way, we can look at the stack trace to know exactly what happened instead of our expected exception.

In Exceptions.kt:
Before:

        else throw ComparisonFailure("Expected ${expectedException.javaObjectType} to be thrown", "${expectedException.javaObjectType}", "${e.javaClass}")

After:

        else throw ComparisonFailure("Expected ${expectedException.javaObjectType} to be thrown", "${expectedException.javaObjectType}", "${e.javaClass}", e)

That logic should/could be applied to every assertions on exceptions, including the withMessage and withCause.

After effect

From the IDE, we can then click on the stack trace of the exception that caused the assertion to fail to be brought to the line that caused it in the code AND know exactly what happened from its message.

Should Throw Used to be able to catch AssertionExceptions

This used to work (1.21), now it leaks the exception (1.29).

@Test
fun `Catch assertion exception`() {
    {
        assertEquals("!", "@")
    } `should throw` AssertionError::class
}

Sorry, maybe that didn't work in 1.21, but this did:

@Test
fun `Catch assertion exception (the exception)`() {
    {
        assertEquals("!", "@")
    } `should throw the Exception` AssertionError::class
}

Boolean's shouldBeTrue/shouldBeFalse extension showing incorrect error message

Hi all,

Running something like:

true.shouldBeFalse()

prints the following exception to the console:

null
java.lang.AssertionError
	at org.junit.Assert.fail(Assert.java:86)
	at org.junit.Assert.assertTrue(Assert.java:41)
	at org.junit.Assert.assertFalse(Assert.java:64)
	at org.junit.Assert.assertFalse(Assert.java:74)
	at org.amshove.kluent.BasicKt.shouldBeFalse(Basic.kt:28)
...

the error message is misleading (null) and it could be improved to something more descriptive.

Add contribution guidelines

At the moment there is no clear statement on how contributions should be done.

In the past the workflow was to create a fork and create a pull request from there on.

This workflow seems natural to Github, so might as well right it down into a CONTRIBUTION.md :-)

In addition, we could add people who are frequently contribution as collaborators, so they can create branches directly in this repository (which also gives them more credit, which they deserve, than mentioning in the changelog).

Does not work on Android projects

Use:

import org.amshove.kluent.mock
val m: AppData = mock(AppData::class)

Error:

java.lang.NoClassDefFoundError: Failed resolution of: Lorg/amshove/kluent/MockingKt;
at com.myproject.tests.Test.testSomething(Test.kt:91)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
at android.support.test.internal.statement.UiThreadStatement.evaluate(UiThreadStatement.java:55)
at android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:270)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:59)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:262)
at com.jakewharton.u2020.U2020TestRunner.onStart(U2020TestRunner.java:22)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1932)
Caused by: java.lang.ClassNotFoundException: Didn't find class "org.amshove.kluent.MockingKt" on path: DexPathList[[zip file "/system/framework/android.test.runner.jar", zip file "/data/app/com.myproject.test-2/base.apk", zip file "/data/app/com.myproject-2/base.apk"],nativeLibraryDirectories=[/data/app/com.myproject.test-2/lib/x86, /data/app/com.myproject-2/lib/x86, /data/app/com.myproject.test-2/base.apk!/lib/x86, /data/app/com.myproject-2/base.apk!/lib/x86, /system/lib, /vendor/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:380)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
... 34 more

Kluent cannot use shouldThrow on nullable functions

Kluent's should*Throw only works on lambdas that return non-null.
The code below does not compile as shouldNotThrow is an extension on Any, not Any?

val func = { null }
func shouldNotThrow AnyException

Lambda logic assertions

Just had some use cases where I was missing some infix assertions.
In my example I basically want to assert that a List contains some String which is not blank.

My initial solution was this:

val specs: List<String>
specs.filter(String::isNotBlank).shouldNotBeEmpty()
specs should { any(String::isNotBlank) }
specs shouldContainSomeWhere String::isNotBlank

The implementation looks like this:

infix inline fun <T> T.should(logic: T.() -> Boolean) = if (logic(this)) Unit else throw AssertionError()
infix inline fun <T> List<T>.shouldContainSomeWhere(logic: T.() -> Boolean) = if (any(logic)) Unit else throw AssertionError()

The cool thing is that you can pass function references ๐Ÿ‘

There are many more applications for this.
What do you think?

Common non-infix assertions

The following common assertions should be implemented:

Collections:

  • shouldBeEmpty()
  • shouldNotBeEmpty()

String/CharSequence:

  • shouldBeEmpty()
  • shouldNotBeEmpty()

String?/CharSequence?

  • shouldBeNullOrEmpty()
  • shouldNotBeNullOrEmpty()

Nullable types:

  • shouldBeNull()
  • shouldNotBeNull()

Boolean:

  • shouldBeTrue()
  • shouldBefalse()
  • shouldNotBeTrue()
  • shouldNotBeFalse()

Kluent 2.0 Roadmap

I'd like to open a discussion about what we should do and drop with the next major version of Kluent.
@javatarz did a lot of work to make Kluent independent of JUnit (and specific test runners in general), thanks for that!

During those PRs (#71 #72) we started a discussion about what we could do and what we could drop with the next major version.
I would love to have a lot of feedback and opinions here :)
We should atleast give @Egorand , @eburke56 , @javatarz, @guenhter and @goreRatzete a chance to state their opinions here ๐Ÿ‘

Dropping support

Mocking

#73 Is already a proposal to drop the mocking features in Kluent. I do agree with @Egorand points and I think it fits into the "no opinion" discussion. If we don't want to force an opinion on a test runner, we also shouldn't do that on mocking. In the beginning of Kluent I started the mocking support with plain java Mockito which didn't work out really well. Later we transitioned to mockito-kotlin and kept our API backwards compatible, but it still doesn't feel great. Kluent doesn't support all kinds of features that a mocking framework is bringing in and it also led to a lot of confusion (#62).

I can see multiple ways of doing this. We could either deprecate mocking in the next 1.x version and drop it completely in 2.x, don't deprecate it (as in keep as it is) in 1.x and drop it in 2.x or also maintain it in 2.x.

Platform independence

Since Kotlin already supports other targets than the JVM (e.g. JavaScript) and more platforms are being worked on (Kotlin native) we could try to take this next major step to also be platform independent.

What that means is that we get rid of all external dependencies (e.g. JUnit) and only use builtin Kotlin functionality.
@javatarz already experimented this within #72 and could give some insights on this.
What we do need if we go into this direction is having tests builtin for each platform, to make sure we don't break anything.

Even if we can get rid of our Java dependencies, we still have dependencies on the Java library, because we do have assertions for java.time.* and java.io.File. I'm not sure if we can be completely platform independent (as in Kotlin platforms) with just maintaining one project.
Having only one core artifact for the Kotlin stdlib and then platform specific assertions (dependent on the core artifact) for Java specific stuff, Android specific stuff and so on, aggregated into one Github organization, might be better in the future.

Android

I also see Android as a kind of another platform, because we are locked in Java 1.6 there. @eburke56 has already contributed logic into our buildsystem so that we can have a specific artifact for Android (e.g. no backtick names). I would definitely want to support Android further.

Junit 5

Once junit 5 is released in a stable manner there should be a Kluent version targeting it.
The goal is to not break code using the current Kluent version, which can be accomplished if junit 5 is backwards compatible.

Make shouldNotBeNull return non-null instance

Sometimes you want to test whether a nullable instance is actually null.
Most often I want to run futher tests on this instance afterwards.

It would be nice if the shouldNotBeNull fun returned a non null type when the test passes (and throws if not).

Sample implementation:

fun <T : Any> T?.shouldNotBeNull(): T = this ?: throw AssertionError("Expected this to not be null")

This allows one to write the following code:

val user = userSource.findUser(details.email).shouldNotBeNull()
user.email.shouldNotBeBlank()
articleSource.insertArticle(user, it)

Without having to !! every user reference.

1 shouldNotBeGreaterThan 1

I am running the following code:
1 shouldNotBeGreaterThan 1

and get the following Error:
java.lang.AssertionError: Expected 1 to not be greater than 1

One is not greater than one, so the Test should pass, right?

The underlying assertion is actually checking if x is smaller than y.

infix fun Int.`should not be greater than`(theOther: Int) = assertTrue("Expected $this to not be greater than $theOther", this < theOther)

Expected, Actual message for shouldNotContain

I have been using the Collection.shouldNotContain method to verify that my Collection does NOT contain an item.

However I found the output on fail quite confusing:

image

It shows the item that I do not want to be in the Collection as Expected, and the Collection as actual.

In other words it looks as if it was actually expected that the item was in the Collection.

I will probably look into this soon.

Also let's make some progress on common assertions like String.shouldNotBeNullOrBlank !

JUnit and Mockito versions

Hi! Thanks for the nice library!

I wonder why you use
compile 'junit:junit:4.11'
and
compile 'org.mockito:mockito-core:2.1.0'
while both have a newer versions (4.12 and 2.7.19)?

Compiled by a pre-release version of Kotlin

Class 'org.amshove.kluent.AssertionsKt' is compiled by a pre-release version of Kotlin and cannot be loaded by this version of the compiler

Using Kotlin 1.1.0-rc-91. You might probably want to have separate branches/releases, one for Kotlin 1.0.6 and another for 1.1.0 which is about to hit stable version.

Mockito 2

Once Mockito v2 is released (currently in RC state) the dependencies should be updated to the stable version without breaking existing Kluent code.

Assertion error shows precious element as incorrect

Hi!
Steps to reproduce:

  1. import org.amshove.kluent.shouldEqual to your project
  2. Create 2 arrays, e.g.
    val arrayOne= arrayOf("One", "Two", "Three")
    val arrayTwo= arrayOf("One", "Two", "Four")
  3. Compare 2 arrays with shouldEqual

Actual result:

arrays first differed at element [2]; 
Expected :[Four]
Actual   :[Three]

error appeared. Error says that arrays differed at element 2.

Expected result: Correct element number should be shown in assertion error.

Thanks for your product!

Missing assertions

I have some function that returns a nullable object and, in certain conditions, throws an exception.
fun someFunction(param: Int): SomeType?
So, I do
val theFunction = { someFunction(-1) }
but the type of theFunction is () -> Any? and doesn't apply the should throw assertion because it's expects () -> Any.
theFunction shouldThrow RuntimeException::class // doesn't work
It's possible to add this assertions?

ShouldNotThrow message is reversed

My code: func shouldNotThrow Exception::class

Exception being thrown:
org.junit.ComparisonFailure: Expected class java.lang.Exception to not be thrown expected:<class [pureconnect.exceptions.Data]Exception> but was:<class [java.lang.]Exception>

Expected :class pureconnect.exceptions.DataException
Actual :class java.lang.Exception

So it says it expected the actual exception, and actual shows my expected exception.

Here is the code from Kluent:
fail("Expected ${expectedException.javaObjectType} to not be thrown", "${e.javaClass}", "${expectedException.javaObjectType}")

Iterable<T> return types have to be revisited

I was just messing with the latest
fun <T> Iterable<T>.shouldNotBeEmpty() = this.apply { assertNotEmpty(this, "Iterable") }

my code looks like this:

LovMapper()
            .getTypes()
            .groupBy(RelationTable::country)["DK"]
            .shouldNotBeNull()
            .shouldNotBeEmpty()
            .forEach(::println)

I noticed that the shouldNotBeEmpty call returns an Iterable, no matter what the actual receiver type is.

Most of the Iterable funs could be changed to something like this:
fun <R: Iterable<*>> R.shouldNotBeEmpty(): R = apply { ... }

In this way, they preserve the actual type.

shouldNotBeEmpty message

The error message of a failing Collection.shouldNotBeEmpty reads:

Expected the Iterable to contain no elements

But actually what it should say is: Expected the Iterable to contain elements.

`itAnswers` should allow original Mockito Answer types

In order to return the first argument using the infix notations, this is what I am required to do without any additional functions:

When calling questionService.updateQuestion(any()) itAnswers { it.getArgument(0) }

Rather, in the original Mockito or even in com.nhaarman:mockito-kotlin I can do this notation:

whenever(questionService.updateQuestion(any())).then(returnsFirstArg<Question>())

In order to achieve this, I must use the following function that should be added to your API:

infix fun <T> OngoingStubbing<T>.itAnswers(value: Answer<T>): OngoingStubbing<T> = this.thenAnswer(value)

You could also include these to make the grammar more accurate with the arguments:

fun <T> withFirstArg(): Answer<T> = org.mockito.AdditionalAnswers.returnsFirstArg()
fun <T> withSecondArg(): Answer<T> = org.mockito.AdditionalAnswers.returnsSecondArg()
fun <T> withThirdArg(): Answer<T> = org.mockito.AdditionalAnswers.returnsArgAt(3)
fun <T> withFourthArg(): Answer<T> = org.mockito.AdditionalAnswers.returnsArgAt(4)
fun <T> withLastArg(): Answer<T> = org.mockito.AdditionalAnswers.returnsLastArg()

The combination of this all allows me to do the following:

When calling questionRepo.save(any(Question::class)) itAnswers withFirstArg()

Dependency of this project causes a warning during build

This project depends on mockito-kotlin:1.3.0 which in turn depends on kotlin-reflect:1.0.6. This causes a warning because the current version of Kluent itself pulls kotlin-reflect:1.1.3-2.

Warning:Kotlin: Runtime JAR files in the classpath should have the same version. These files were found in the classpath:
    C:/Users/<usr>/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-jre8/1.1.3-2/kotlin-stdlib-jre8-1.1.3-2.jar (version 1.1)
    C:/Users/<usr>/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib/1.1.3-2/kotlin-stdlib-1.1.3-2.jar (version 1.1)
    C:/Users/<usr>/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-jre7/1.1.3-2/kotlin-stdlib-jre7-1.1.3-2.jar (version 1.1)
    C:/Users/<usr>/.m2/repository/org/jetbrains/kotlin/kotlin-reflect/1.0.6/kotlin-reflect-1.0.6.jar (version 1.0)

Let assertions return their parameter on the happy path

(came up in #90)

Some assertions should return their parameter back to the caller, to use them as a kind of verification in unit tests.

This will also make chaining assertions possible

theString
    .shouldNotBeNull()
    .shouldNotBeEmpty()

Example:

infix fun Any?.shouldBeInstanceOf(className: Class<*>) = assertTrue("Expected $this to be an instance of $className", className.isInstance(this))

to

inline fun <reified T: Any> Any.shouldBeInstanceOf() : T = if(this::class.isInstance(T::class)) this as T else throw AssertionError("Expected $this to be an instance of ${T::class.qualifiedName}")

which has to be a separate method to not break existing code.

This would allow:

open class Base {
    fun doSomething() = println("Base")
}

class Child : Base() {
    fun different() = println("Child")
}

fun main(args: Array<String>) {
    val base : Base = Child()
    // base.different() - Doesn't compile, not of type Child
    val child = base.shouldBeInstanceOf<Child>()
    child.different()
}

Currently identified assertions:

shouldBeInstanceOf
All numerical assertions in form of: shouldBeGreaterThan
All String and CharSequence assertions
The generic should method

Common String operations

I am frequently using the following common String operations and their negated equivalents in my tests:

String shouldContain CharSequence
String shouldContain Regex
String shouldStartWith String

It would be nice to include them in Kluent.

What do you think?

Wrong Verify

The Verify is not working fine when you use com.nhaarman.mockito_kotlin.check as a mock argument.
I have created a repo where I do the same test with and without Kluent where you could check the behavior that I describe here
https://github.com/JcMinarro/TestKluent

Maven pom refers to "plus sign" versions of dependencies

I'm using maven 3.3.9, and am unable to resolve these dependencies from the Kluent 1.1.7 pom:

  • org.jetbrains.kotlin:kotlin-stdlib:jar:1.1.+
  • org.jetbrains.kotlin:kotlin-reflect:jar:1.1.+
  • com.nhaarman:mockito-kotlin:jar:1.3.+

That I'm aware of, the "plus sign" is not valid for resolving. The documentation on this is a bit scattered, but I believe this works: http://maven.apache.org/enforcer/enforcer-rules/versionRanges.html.

Perhaps [1.1,1.2) would work (meaning at least 1.1, but not yet 1.2)?

Failed to resolve mockito-kotlin dependency

Hi!
I have

Error:Failed to resolve: com.nhaarman:mockito-kotlin-kt1.1:1.5.+

in the version 1.32.

I think it's because of 1.5.+ versioning.

Excluding the module and adding dependency with 1.5.0 solves the issue.

documentation: verify-mockedMethod-has-been-called-n-times

Hi Marcus, I'm a big fan of your library.

But could you please add an example on how to verify that a mocked/stubbed method call has been called n-times.

I'm currently struggling with ...

Verify on apiClient that
apiClient.sendRequest(any()) was called

This asserts method is called exactly once.
But I'd like to assert, that method has been called 2-times or not-more-than-2-times.

Is there an idiomatic way to to that kind of stuff?

Thanks a lot for your help
/Seb

DELETE_ME

Really sorry, it got created by mistake.

Add withCause

It would be nice to be able to assert that an expected exception has a specific cause, like you can assert that it has a specific message. Something like the following:

func `should throw the Exception` MyException::class `with cause` IndexOutOfBoundsException::class

Deprecate mocking-related features

Kluent is great for its assertions, and mocking features seem secondary to the library's purpose. Additionally, using both Kluent and mockito-kotlin is confusing, as it leads to a very long list of auto-complete options when writing mock-creating code. Suggestion is to deprecate the features and remove in Kluent 2.x.

can't use Kluent in Android Instrumentation test

Kluent has lots of java8 APIs and while using proguard I could build
-dontwarn org.amshove.kluent.**

I could not deploy the tests to the device:

INSTALL_FAILED_DEXOPT
Unknown failure (Failure - not installed for 0)

It'd be nice to have an kluent-android which supports instrumentation tests

Add Assertions for Maps

According to PR #9 we should implement more operations to test Maps.

  • shouldHaveKey (thanks to @goreRatzete )
  • shouldNotHaveKey (thanks to @goreRatzete )
  • shouldHaveValue
  • shouldNotHaveValue
  • shouldContain (pair)

Android 1.31 version have null inside inner dependencies versions

If you check the pom for that version on bintray you can see:

Library: 'org.amshove.kluent:kluent-android:1.31'

Library pom example:

 <groupId>org.jetbrains.kotlin</groupId>
      <artifactId>kotlin-stdlib</artifactId>
      <version>null</version>
      <scope>runtime</scope>
...

And then this version is not usable.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.