Package org.broadleafcommerce.test.junit
Class JUnitSpringBootAdminIntegrationSetup
java.lang.Object
org.broadleafcommerce.test.junit.JUnitSpringBootAdminIntegrationSetup
@ExtendWith(org.springframework.test.context.junit.jupiter.SpringExtension.class)
@SpringBootTest(classes=AdminApplication.class)
@TestPropertySource(locations="classpath:/config/bc/overrideprops/admin_springboot_testoverrides.properties")
@Import(AdminSpringBootTestConfiguration.class)
public abstract class JUnitSpringBootAdminIntegrationSetup
extends Object
This is a convenient base class for launching a spring boot test against the admin application. The primary testing technologies
employed here are JUnit and Spring's MockMVC. This integration test focuses on testing the controller API. It has the following beneficial attributes:
- The test is much less brittle than a traditional presentation-tier functional test, but with nearly the same full lifecycle coverage benefits.
- Development iteration and test execution times are less.
- This test will generally survive a admin pipeline refactor without much change. It has good longevity characteristics.
- Raw database confirmation of operations is trivial.
JUnitSpringBootAdminIntegrationSetup and employ standard MockMVC test calls to simulate
admin controller interactions. The AdminTestHelper is included for convenience API around starting an
Entity-Manager-In-View session for retrieving and verifying records from the database. This is useful when directly
confirming data results from admin MockMVC calls.
JUnitSpringBootAdminIntegrationSetup already introduces the most likely filters and user request roles required
for admin interaction. Extending tests can customize by overriding getOrderedFilters(Filter...) and
getRequestRoles(String...). Note, this is different than the usage of @WithMockUser, which should be annotated
on your test methods and specify the admin user name to associate with the test.
If you have existing, non-spring-boot tests already running, you'll want to separate the execution of your spring boot
tests. Otherwise, you'll likely run into problems during test app context initialization in regard to some classloader
nuances and static variables. This can be achieved by creating multiple <execution> elements in your
maven-surefire-plugin configuration in your pom.xml. Review the documentation for the maven plugin on how to include and
exclude tests into separate executions. http://maven.apache.org/surefire/maven-surefire-plugin/examples/inclusion-exclusion.html
Several libraries are required to be on the test classpath in order to get admin spring boot testing. You can include the
following in your pom.xml <dependencies> section.
<dependency>
<groupId>org.broadleafcommerce</groupId>
<artifactId>integration</artifactId>
<version>${blc.version}</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.broadleafcommerce</groupId>
<artifactId>integration</artifactId>
<version>${blc.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.broadleafcommerce</groupId>
<artifactId>broadleaf-thymeleaf3-presentation</artifactId>
<version>${broadleaf-presentation.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<version>${spring.security.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring.boot.test.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.broadleafcommerce</groupId>
<artifactId>broadleaf-boot-starter-hsql-database</artifactId>
<version>${database.starter.version}</version>
<scope>test</scope>
</dependency>
An example test will look something like this:
public class MyIT extends JUnitSpringBootAdminIntegrationSetup {
protected AdminTestHelper h;
@Override
public void setUp() throws Exception {
super.setUp();
h = getHelper(AdminTestHelper.class);
}
@Test
@WithMockUser(username = "admin")
public void testProductAdd() throws Throwable {
MvcResult result = getMockMvc().perform(post("/admin/product/new/enterprise-add").contextPath("/admin").accept("text/html")
.param("entityType", ProductImpl.class.getName())
.header("host", "global.local.com"))
.andReturn();
String redirectUrl = result.getResponse().getRedirectedUrl();
Assert.assertTrue(redirectUrl.startsWith("/admin/product"));
Long id = Long.parseLong(redirectUrl.substring(redirectUrl.lastIndexOf("/") + 1, redirectUrl.indexOf("?")));
result = getMockMvc().perform(post("/admin/product/" + id).contextPath("/admin").accept("text/html")
.param("isPostAdd", "true")
.param("entityType", ProductImpl.class.getName())
.param("ceilingEntityClassname", Product.class.getName())
.param("id", String.valueOf(id))
.param("sectionCrumbs", ProductImpl.class.getName() + "--" + id)
.param("fields['defaultSku.name'].value", "Vendor Product")
.param("fields['defaultSku.retailPrice'].value", "12")
.param("fields['defaultCategory'].value", "3002")
.param("fields['url'].value", "/hot-sauces/thing")
.header("host", "global.local.com"))
.andReturn();
Assert.assertEquals(result.getResponse().getStatus(), HttpServletResponse.SC_FOUND);
}
}
Finally, a warning. When the spring-boot-starter-test dependency is on the classpath, MockitoPostProcessor is automatically
included, which causes class scanning while looking for @Configuration classes. This ends up loading some
domain classes in the classloader at startup that interferes with normal Load Time Weaving operations in Broadleaf. As a
result, AdminSpringBootTestConfiguration automatically configures a no-op implementation of MockitoPostProcessor
to avoid the scanning, at the cost of removing Mockito support in the Spring Boot test.- Author:
- Jeff Fischer
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescription<T extends AdminTestHelper>
Torg.springframework.test.web.servlet.MockMvcprotected jakarta.servlet.Filter[]getOrderedFilters(jakarta.servlet.Filter... basicFilters) Override to add filters and change orderingprotected String[]getRequestRoles(String... basicRoles) Override to add or change roles.voidsetUp()
-
Constructor Details
-
JUnitSpringBootAdminIntegrationSetup
public JUnitSpringBootAdminIntegrationSetup()
-
-
Method Details
-
setUp
- Throws:
Exception
-
getMockMvc
public org.springframework.test.web.servlet.MockMvc getMockMvc() -
getHelper
-
getOrderedFilters
protected jakarta.servlet.Filter[] getOrderedFilters(jakarta.servlet.Filter... basicFilters) Override to add filters and change ordering- Parameters:
basicFilters-- Returns:
-
getRequestRoles
Override to add or change roles. These roles are important for anywhere in an admin flow where the HttpServletRequest#isUserInRole API is used.- Parameters:
basicRoles-- Returns:
-