toBeAnInstanceOf

Expects that the type of the subject of this expectation is the defined SubTypeOfSubjectT or a subtype thereof and down-casts the subject to SubTypeOfSubjectT.

Notice, that asserting a function type is flawed. The actual types are ignored as function types erase to Function0, Function1 etc. on byte code level, which means the assertion holds as long as the subject is a function and has the same amount of arguments regardless if the types differ. For instance expect({x: Int -> "hello"}).toBeAnInstanceOf<String -> Unit>{} holds, even though (Int) -> String is clearly not a (String) -> Unit.

More generally speaking, the flaw applies to all generic types. For instance toBeAnInstanceOf<List<String>> would only check if the subject is a List without checking if the element type is actually String. Or in other words expect(listOf(1, 2)).toBeAnInstanceOf<List<String>>{} holds, even though List<Int> is clearly not a List<String>.

Return

An Expect with the new type SubTypeOfSubjectT.

Since

0.17.0

Parameters

SubTypeOfSubjectT

Typically a type which is a subtype of SubjectT in this Expect<SubjectT>.

Samples

val n: Number = 1
expect(n).toBeAnInstanceOf<Int>() toBeGreaterThan 0
//                   | subject is now of type Int

fails {
    expect("A").toBeAnInstanceOf<Long>() toBeLessThan 2L
    //                                      | not shown in reporting as `toBeAnInstanceOf` already fails
}

infix inline fun <SubTypeOfSubjectT : Any> Expect<*>.toBeAnInstanceOf(noinline assertionCreator: Expect<SubTypeOfSubjectT>.() -> Unit): Expect<SubTypeOfSubjectT>(source)

Expects that the type of the subject of this expectation is the defined SubTypeOfSubjectT or a subtype thereof and that it holds all assertions the given assertionCreator creates.

Notice, in contrast to other expectation functions which expect an assertionCreator, this function returns not Expect of the initial type, which was some type T , but an Expect of the specified type SubTypeOfSubjectT. This has the side effect that a subsequent call has only assertion functions available which are suited for SubTypeOfSubjectT. Since Expect is invariant it especially means that an assertion function which was not written in a generic way will not be available. Fixing such a function is easy (in most cases), you need to transform it into a generic from. Following an example:

interface Person
class Student: Person
fun Expect<Person>.foo() = "dummy" // limited only to Person, not recommended
fun <T: Person> Expect<T>.bar() = "dummy" // available to Person and all subtypes, the way to go
fun Expect<Student>.baz() = "dummy" // specific only for Student, ok since closed class

val p: Person = Student()
expect(p) // subject of type Person
.toBeAnInstanceOf<Student> { ... } // subject now refined to Student
.baz() // available via Student
.foo() // not available to Student, only to Person, results in compilation error
.bar() // available via T : Person

Notice, that asserting a function type is flawed. The actual types are ignored as function types erase to Function0, Function1 etc. on byte code level, which means the assertion holds as long as the subject is a function and has the same amount of arguments regardless if the types differ. For instance expect({x: Int -> "hello"}).toBeAnInstanceOf<String -> Unit>{} holds, even though (Int) -> String is clearly not a (String) -> Unit.

More generally speaking, the flaw applies to all generic types. For instance toBeAnInstanceOf<List<String>> would only check if the subject is a List without checking if the element type is actually String. Or in other words expect(listOf(1, 2)).toBeAnInstanceOf<List<String>>{} holds, even though List<Int> is clearly not a List<String>.

Return

An Expect with the new type SubTypeOfSubjectT.

Since

0.17.0

Parameters

SubTypeOfSubjectT

Typically a type which is a subtype of SubjectT in this Expect<SubjectT>.

Samples

val n: Number = 16
expect(n).toBeAnInstanceOf<Int> { // subject is now of type Int
    it toBeGreaterThanOrEqualTo 15
} /* subject remains type Int also after the block
*/ toBeLessThan 20

fails { // because wrong type expected (Long instead of String), but since we use an expectation-group...
    expect("A").toBeAnInstanceOf<Long> {
        it toEqual 43 // ...reporting mentions that subject was expected `to equal: 43`
    }
}

fails { // because sub-expectation fails
    expect(n).toBeAnInstanceOf<Long> {
        it toEqual -1L
    }
}

fails {
    // because you forgot to define an expectation in the expectation-group block
    // use `.toBeAnInstanceOf<Int>()` if this is all you expect
    expect<Number>(1).toBeAnInstanceOf<Int> { }
}