Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test modularization and dependency injection #66

Open
ashleyfrieze opened this issue Nov 30, 2016 · 0 comments
Open

Test modularization and dependency injection #66

ashleyfrieze opened this issue Nov 30, 2016 · 0 comments

Comments

@ashleyfrieze
Copy link
Contributor

ashleyfrieze commented Nov 30, 2016

The most obvious way to modularize tests is to have lots of test classes. This should be the default. With JUnit rules mix-ins there's further modularization.

However, it may be the intent of a test author to create a singular test suite, which is simply too long to express in a single place. Or there may be a reusable test that, dependent on data being set up, operates differently.

Here's the proposal

  • Write a demonstration of dependency injecting suppliers/rules etc from the surrounding test class into a new Test class object, which writes its tests in its parameterised constructor - this is no code change for Spectrum, since you should be able to do it already
    • The class may be a suite or a spec - it wouldn't matter
    • Actually it could be a method too - any method would do
  • Make it easy to add in classes NOT decorated with the @RunWith(Spectrum.class) as sub-suites within the test - this allows us to weave together a user-facing suite (in terms of runner output) from several small classes.

If we add tricks like parallelised running, this sort of option will really really be useful.

Dependency injection

@RunWith(Spectrum.class)
public class MyTest {{
    final Supplier<Thing> thing = let(() -> new Thing());

    new TestWhichUsesThing(thing);
    OtherTestWhichUsesThing.testsFor(thing);
}}

class TestWhichUsesThing (
    TestWhichUsesThing(Supplier<Thing> thing) {
        describe("suite", () -> {
            it("uses thing", () -> { thing.thingy(); });
        });
    }
}

class OtherTestWhichUsesThing(
    static void testFor(Supplier<Thing> thing) {
        describe("suite", () -> {
            it("uses thing", () -> { thing.thingy(); });
        });
    }
}

Suites

Just have an "include" keyword or something

// this is a super suite and it's super sweet
@RunWith(Spectrum.class)
public class MyTest {{
    include(MyOtherTest.class);
    include(MyOtherOtherTest.class);
}}

this may be as simple to implement as

//spectrum class
public static void include(final Class<?> testClass) throws Throwable {
    new ConstructorBlock(testClass).run();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant