Skip to content
CMO & CTO
CMO & CTO

Closing the Bridge Between Marketing and Technology, By Luis Fernandez

  • Digital Experience
    • Experience Strategy
    • Experience-Driven Commerce
    • Multi-Channel Experience
    • Personalization & Targeting
    • SEO & Performance
    • User Journey & Behavior
  • Marketing Technologies
    • Analytics & Measurement
    • Content Management Systems
    • Customer Data Platforms
    • Digital Asset Management
    • Marketing Automation
    • MarTech Stack & Strategy
    • Technology Buying & ROI
  • Software Engineering
    • Software Engineering
    • Software Architecture
    • General Software
    • Development Practices
    • Productivity & Workflow
    • Code
    • Engineering Management
    • Business of Software
    • Code
    • Digital Transformation
    • Systems Thinking
    • Technical Implementation
  • About
CMO & CTO

Closing the Bridge Between Marketing and Technology, By Luis Fernandez

Testing with Spring: Fast Feedback for Big Systems

Posted on March 9, 2015 By Luis Fernandez

Coffee, a red build, and the twenty minute wait

Friday night deploy. Fresh coffee. One scary log line. We rolled back in time, but the worst part was not the bug. It was the twenty minute test run to learn what we already suspected. Big Spring apps can feel like a slow train when all you want is a quick bike ride. With Apple teasing new stuff on stage tomorrow, I do not want to spend my morning staring at a progress bar. I want fast feedback.

This is what has worked for me on large Spring projects where the codebase is big and the team is bigger. Keep the story simple. Keep the build honest. Make Spring help, not slow you down.

Technical playbook for fast feedback with Spring

1. The quick path: pure unit tests. No Spring container. No context. Just Java and mocks. These should run in under ten seconds on a laptop.

public class PriceServiceTest {

  private DiscountCalculator calculator = mock(DiscountCalculator.class);
  private PriceService service = new PriceService(calculator);

  @Test
  public void appliesDiscount() {
    when(calculator.apply(any(BigDecimal.class))).thenReturn(new BigDecimal("90.00"));

    BigDecimal price = service.finalPrice(new BigDecimal("100.00"));

    assertEquals(new BigDecimal("90.00"), price);
    verify(calculator).apply(new BigDecimal("100.00"));
  }
}

2. Wiring tests with Spring without paying full price. Spin up a tiny context that loads only the beans you need. Avoid giant component scans. Reuse the cached ApplicationContext and avoid @DirtiesContext unless you change static state.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {AppConfig.class, TestOnlyConfig.class})
@ActiveProfiles("test")
public class PaymentWiringTest {

  @Autowired PaymentService paymentService;
  @Autowired FakeGateway fakeGateway;

  @Test
  public void talksToGateway() {
    fakeGateway.willApprove();
    boolean ok = paymentService.charge("42", new BigDecimal("10.00"));
    assertTrue(ok);
  }
}

@Configuration
@Profile("test")
class TestOnlyConfig {
  @Bean public Gateway fakeGateway() { return new FakeGateway(); }
}

3. HTTP without a container. Controllers can be tested with MockMvc in standalone mode. No servlet container, no web app context.

public class OrderControllerTest {

  private MockMvc mvc;

  @Before
  public void setup() {
    OrderController controller = new OrderController(new InMemoryOrderRepo());
    mvc = MockMvcBuilders.standaloneSetup(controller).build();
  }

  @Test
  public void returnsCreated() throws Exception {
    mvc.perform(post("/orders").content("{\"sku\":\"abc\",\"qty\":1}")
        .contentType(MediaType.APPLICATION_JSON))
       .andExpect(status().isCreated());
  }
}

4. Real database, still fast. Use an in memory database for most checks. Keep a tiny schema. Reset with transactions.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = DbConfig.class)
@Transactional
public class UserRepositoryDbTest {

  @Autowired JdbcTemplate jdbc;
  @Autowired UserRepository repo;

  @Test
  public void savesAndReads() {
    repo.save(new User("ana@example.com"));
    assertEquals(1, jdbc.queryForObject("select count(*) from users", Integer.class).intValue());
  }
}

@Configuration
class DbConfig {
  @Bean DataSource ds() {
    return new EmbeddedDatabaseBuilder()
      .setType(EmbeddedDatabaseType.H2)
      .addScript("classpath:schema.sql").build();
  }
}

5. Split the build. Let Maven or Gradle run fast checks first, and the heavier suite later. Names like *Test for the quick ones and *IT for the slow ones keep your CI honest.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <configuration>
    <includes><include>**/*Test.java</include></includes>
  </configuration>
</plugin>
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-failsafe-plugin</artifactId>
  <executions>
    <execution>
      <goals><goal>integration-test</goal><goal>verify</goal></goals>
      <configuration>
        <includes><include>**/*IT.java</include></includes>
      </configuration>
    </execution>
  </executions>
</plugin>

Extra points you can add a Docker backed suite on CI for a real Postgres or a stubbed payment gateway. Keep that for the slower lane so your laptop stays snappy.

Manager view: pay for speed once, enjoy it daily

Your team gets paid to learn fast. Waiting ten minutes to know if a change was safe kills flow. Set simple targets and make them visible. Unit checks under 10 seconds. Wiring checks under 60 seconds. Full suite under 5 minutes on CI. Budget time for test data builders, small Spring configs, and a clean pipeline with surefire and failsafe. This is cheaper than one bad outage and a long night.

Also watch your context size. A giant auto scan feels easy today and hurts every day after. Be explicit with config classes and profiles. Your future self will say thanks.

Your turn

– Measure your local build. If the quick lane is over 60 seconds, cut your Spring context by half this week.

– Pick one controller test and switch to MockMvc standalone. Time the difference.

– Move at least five slow checks to the slower lane with *IT and run them on Jenkins or Travis after merge.

Send me your before and after numbers. If you beat these targets, I will buy the next coffee. If tomorrow’s stage show gets you a new watch, even better. But the real win is a build that answers fast so you can ship with a smile.

Development Practices Software Architecture Software Engineering

Post navigation

Previous post
Next post
  • Digital Experience (94)
    • Experience Strategy (19)
    • Experience-Driven Commerce (5)
    • Multi-Channel Experience (9)
    • Personalization & Targeting (21)
    • SEO & Performance (10)
  • Marketing Technologies (92)
    • Analytics & Measurement (14)
    • Content Management Systems (45)
    • Customer Data Platforms (4)
    • Digital Asset Management (8)
    • Marketing Automation (6)
    • MarTech Stack & Strategy (10)
    • Technology Buying & ROI (3)
  • Software Engineering (310)
    • Business of Software (20)
    • Code (30)
    • Development Practices (52)
    • Digital Transformation (21)
    • Engineering Management (25)
    • General Software (82)
    • Productivity & Workflow (30)
    • Software Architecture (85)
    • Technical Implementation (23)
  • 2025 (12)
  • 2024 (8)
  • 2023 (18)
  • 2022 (13)
  • 2021 (3)
  • 2020 (8)
  • 2019 (8)
  • 2018 (23)
  • 2017 (17)
  • 2016 (40)
  • 2015 (37)
  • 2014 (25)
  • 2013 (28)
  • 2012 (24)
  • 2011 (30)
  • 2010 (42)
  • 2009 (25)
  • 2008 (13)
  • 2007 (33)
  • 2006 (26)

Ab Testing Adobe Adobe Analytics Adobe Target AEM agile-methodologies Analytics architecture-patterns CDP CMS coding-practices content-marketing Content Supply Chain Conversion Optimization Core Web Vitals customer-education Customer Data Platform Customer Experience Customer Journey DAM Data Layer Data Unification documentation DXP Individualization java Martech metrics mobile-development Mobile First Multichannel Omnichannel Personalization product-strategy project-management Responsive Design Search Engine Optimization Segmentation seo spring Targeting Tracking user-experience User Journey web-development

©2025 CMO & CTO | WordPress Theme by SuperbThemes