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

Add Spring-Integratiom #85

Open
Writtscher opened this issue Mar 13, 2015 · 5 comments
Open

Add Spring-Integratiom #85

Writtscher opened this issue Mar 13, 2015 · 5 comments

Comments

@Writtscher
Copy link

Enhacement:

I'd like to contribute and add ,as soon as I have time, a spring integration.

For example a LambdaBehaveSpringRunner that starts a spring context that provides to inject spring dependencies.

What you think?

@RichardWarburton
Copy link
Owner

I think some kind of spring integration would be good. I suspect a good idea would be to try and think up a few examples of what such an API would look like. Perhaps you can show some example code of what you would like it to look like?

@Writtscher
Copy link
Author

I have implemented a first version. Have a look at it and share your thoughts. I had to copy paste some code of you as there is a lot of static. We should think about some inheritance..

Have a look lambda-behave-spring

(It's not final.. as it does not support every spring application context.. only tested with annotation...)

@woprzech
Copy link

woprzech commented Jan 8, 2017

Since Spring 4.2 you can use Spring Method Rule that allow you to be independent of any Runner.

@sworisbreathing
Copy link

I've tried @woprzech's suggestion but couldn't get that working with a @SpringBootTest annotated test class. Will try lambda-behave-spring.

@sworisbreathing
Copy link

sworisbreathing commented Sep 29, 2017

ok so lambda-behave-spring didn't work for me because it only works with the @ContextConfiguration annotation. However I was able to get something working based on @woprzech's suggestion, using Spring Boot 1.5.7.RELEASE, JUnit 4.12, and lambda-behave 0.4.

In this case the application under test is a Spring Boot app exposing a simple REST API, tested with RestAssured. Here's the entire codebase (package names omitted):

Application.java:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

  public static void main(String... args) {
    SpringApplication.run(new Application(), args);
  }
}

HelloWorldAPI.java:

import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/v1/hello-world-api")
public class HelloWorldAPI {
  
  @RequestMapping(value = "/hello-world", produces = MediaType.APPLICATION_JSON_VALUE)
  public ResponseEntity<?> helloWorld() {
    return ResponseEntity.ok("{\"message\": \"Hello, World!\"}");
  }
}

And finally the test class:

import java.lang.reflect.Method;

import com.insightfullogic.lambdabehave.JunitSuiteRunner;
import static com.insightfullogic.lambdabehave.Suite.describe;

import com.jayway.restassured.RestAssured;
import static com.jayway.restassured.RestAssured.when;
import com.jayway.restassured.response.Response;

import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.runner.RunWith;

import org.springframework.boot.test.context.SpringBootTest;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
import org.springframework.core.env.Environment;
import org.springframework.test.context.TestContextManager;
import org.springframework.test.context.junit4.rules.SpringClassRule;
import org.springframework.test.context.junit4.rules.SpringMethodRule;
import org.springframework.util.ReflectionUtils;

@RunWith(JunitSuiteRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
public class HelloWorldAPITest {

  /*
   * The class and method rules work as an alternative to running with
   * SpringRunner/SpringJUnit4ClassRunner.
   *
   * You absolutely need both, and the class rule must be public, static, and final.
   */
  @ClassRule
  public static final SpringClassRule classRule = new SpringClassRule();

  @Rule
  public SpringMethodRule methodRule = new SpringMethodRule();

  /*
   * following the other lambda-behave examples, we use double-brace
   * initialization.
   */
  {
    /*
     * The first argument to describe MUST be the name of the class where the
     * SpringClassRule is defined (in other words, the test class).
     *
     * If we use an arbitrary string, the class rule will throw a
     * NullPointerException before the test executes.
     */
    describe(HelloWorldAPITest.class.getName(), it -> {

      /*
       * Here we are telling RestAssured what port to connect to.
       *
       * Unfortunately we don't have direct access to the test context that
       * Spring set up, so we will need to use a bit of reflection before we
       * can access that configuration property.
       */
      it.isSetupWith(() -> {
        Method getTestContextManagerMethod = ReflectionUtils.findMethod(SpringClassRule.class, "getTestContextManager", Class.class);
        ReflectionUtils.makeAccessible(getTestContextManagerMethod);
        TestContextManager manager = (TestContextManager) getTestContextManagerMethod.invoke(classRule, HelloWorldAPITest.class);
        Environment env = manager.getTestContext().getApplicationContext().getEnvironment();
        int port = env.getProperty("local.server.port", Integer.class);
        RestAssured.port = port;
      });

      // Test execution goes here.
      it.should("work", expect -> {
        Response response = when().get("/v1/hello-world-api/hello-world");

        expect.that(response.statusCode()).isEqualTo(200);
        expect.that(response.body().<String>path("message")).isEqualTo("Hello, World!");
      });
    });
  }

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants