Coder Social home page Coder Social logo

dam5s / aspen Goto Github PK

View Code? Open in Web Editor NEW
33.0 6.0 2.0 162 KB

Aspen is a simple test runner for Kotlin that allows you to write tests using your own DSL.

License: MIT License

Kotlin 100.00%
kotlin aspen-spring aspen dsl kotlin-testing junit testing java test-runner

aspen's Introduction

Aspen is a JUnit runner for Kotlin. It's inspired by Ruby's RSpec syntax, the default DSL has a lot more restrictions, but you can create your own DSL if it does not fit your needs.

Gradle usage

dependencies {
    testImplementation "com.github.dam5s.aspen:aspen:2.1.0"
    testImplementation "com.github.dam5s.aspen:aspen-spring:2.1.0"
}

repositories {
    maven { url 'https://jitpack.io' }
}

You can also download the JAR files from the release and add them to your path.

Example

If you were to use AssertJ for assertions.

class CompanyControllerTest: Test({

    val mockRepo = mock(CompanyRepository::class.java)
    val controller = CompanyController(mockRepo)
    
    useRule(MyAwesomeRule())

    before {
        reset(mockRepo)
    }

    describe("#create") {
        test {
            val company = Company(name = "Wayne Enterprises")
            doReturn(company).upon(mockRepo).create(any())

            val response = controller.create("Wayne Ent.")

            assertThat(response).isEqualTo(Response(company, true))
            verify(mockRepo).create("Wayne Ent.")
        }

        test("repository creation error") {
            doReturn(null).upon(mockRepo).create(any())

            val response = controller.create("Wayne Ent.")

            assertThat(response).isEqualTo(Response(null as Company?, false))
        }
    }
})

You can focus a test by prefixing changing test to ftest. Then only this or these tests get run. For example running the tests above after replacing the second test with

ftest("repository creation error") {
    doReturn(null).upon(mockRepo).create(anyString())

    val response = controller.create("Wayne Ent.")

    assertThat(response).isEqualTo(Response(null as Company?, false))
}

Only that second test will get run.

Writing table based tests (a.k.a. Parameterized tests) can be as simple as the following

class ReservationTestExample : Test({

    describe("#amount") {
        class AmountData
        (name: String, val status: Status, val amount: Int) : TestData(name)

        val data = listOf(
            AmountData("when status is OPEN", Status.OPEN, 0),
            AmountData("when status is STARTED", Status.STARTED, 0),
            AmountData("when status is BILLED", Status.BILLED, 100),
            AmountData("when status is PAID", Status.PAID, 100)
        )

        tableTest(data) {
            assertThat(Reservation(status).amount()).isEqualTo(amount)
        }
    }
})

Restrictions

There can only be one before block and it has to be at the top level. describe blocks can only contain test blocks and they cannot be nested further. Unlike RSpec, there are no it blocks. We are trying to encourage having expressive assertions that should describe correctly your expectations.

Why all these restrictions?

The goal of this library is to make your tests a little easier to organize. But we do believe that the JUnit style is sufficient for testing and encourages making your test code clear and easy to read, so we are not adding any unnecessary complexity.

But I want my own DSL!

We tried to make custom Domain Specific Languages easy to write. You can see an example of a second DSL we created allowing nesting by following these links:

Spring Support

Aspen supports Spring!

@RunWith(SpringTestTreeRunner::class)
@SpringApplicationConfiguration(ExampleApplication::class)
@WebIntegrationTest("server.port:0")
class SpringApplicationTest : Test({

    val message: String = inject("myMessage")
    val port = injectValue("local.server.port", Int::class)

    val client = OkHttpClient()

    test("GET /hello") {
        val request = Request.Builder()
            .url("http://localhost:$port/hello")
            .build()

        val response = client.newCall(request).execute()

        val body = response.body().string()
        assertThat(body).isEqualTo("""{"hello":"$message"}""")
    }
})

More examples

You will find actually up-to-date examples that are part of our test suite in the following locations:

Blog posts

aspen's People

Contributors

dam5s avatar jackman3005 avatar mikegehard avatar titopandub 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

aspen's Issues

Support JUnit5

The current implementation (2.1) does not seem to support JUnit5, complaining that

!!! JUnit version 3.8 or later expected:

I have removed JUnit 4 from the classpath, and included JUnit5. 'Pure' JUnit5 tests run just fine, so I know the dependencies are present, as expected.

Refactoring: use parameter default values

fun test(block: Test.() -> Unit) {
    test("unnamed test #${++unnamedContexts}", block)
}

fun test(name: String, block: Test.() -> Unit) {
    tests.add(Test(name, block))
}

fun ftest(block: Test.() -> Unit) {
    ftest("unnamed test #${++unnamedContexts}", block)
}

fun ftest(name: String, block: Test.() -> Unit) {
    focusedTests.add(Test(name, block))
}

Should be:

fun test(name: String = "unnamed test #${++unnamedContexts}", block: Test.() -> Unit) {
    tests.add(Test(name, block))
}

fun ftest(name: String = "unnamed test #${++unnamedContexts}", block: Test.() -> Unit) {
    focusedTests.add(Test(name, block))
}

Spring Auto-configured tests support

Spring Boot 1.4 brought in concept of 'slices' for testing seen here. When attempting to use @WebMvcTest with @MockBean, only the first test passes and the rest error with mockRecipeRepository cannot have an existing value. It seems like @MockBean isn't being reset, not sure if there's just no 1.4 support yet. Or the incredibly likely I skipped a step :-)

Here's the branch of the sample repo with the issue recreated :
https://github.com/moleske/restaurant-kotlin/blob/try-and-use-webmvctest/src/test/kotlin/com/oleske/recipe/RecipeControllerTest.kt

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.