MindIQ Academy

09 - Spring Testing Notes

A beginner-to-advanced guide to Spring testing, JUnit 5, Mockito, @SpringBootTest, @WebMvcTest, @DataJpaTest, MockMvc, and Testcontainers for Spring Professional Certification candidates. Covers Spring Framework 6 and Spring Boot 3 concepts.


Table of Contents

  1. Why Testing Matters in Spring
  2. JUnit 5
  3. Mockito
  4. @SpringBootTest
  5. @WebMvcTest
  6. @DataJpaTest
  7. MockMvc
  8. Testcontainers
  9. Choosing the Right Spring Test Annotation
  10. Common Test Dependencies
  11. Interview Questions
  12. Cheat Sheet
  13. Key Takeaways

1. Why Testing Matters in Spring

Testing in Spring applications usually happens at multiple levels:

LevelPurposeCommon Tools
Unit testTest one class in isolationJUnit 5, Mockito
Slice testTest one layer of the application@WebMvcTest, @DataJpaTest
Integration testTest multiple Spring components together@SpringBootTest, Testcontainers
End-to-end style testTest application behavior through HTTP or APIsMockMvc, TestRestTemplate, WebTestClient

The goal is not to load the whole Spring context for every test. Use the smallest test scope that proves the behavior.

2. JUnit 5

JUnit 5 is the default testing framework used by modern Spring Boot projects.

JUnit 5 has three main parts:

ComponentPurpose
JUnit PlatformLaunches testing frameworks on the JVM
JUnit JupiterProgramming model and annotations for JUnit 5
JUnit VintageRuns older JUnit 3 and JUnit 4 tests

Common JUnit 5 Annotations

AnnotationPurpose
@TestMarks a test method
@BeforeEachRuns before each test method
@AfterEachRuns after each test method
@BeforeAllRuns once before all tests
@AfterAllRuns once after all tests
@DisplayNameGives a readable test name
@DisabledSkips a test
@NestedGroups related tests
@ParameterizedTestRuns the same test with multiple inputs
@ValueSourceSupplies simple values to a parameterized test
@CsvSourceSupplies comma-separated arguments
@MethodSourceSupplies arguments from a method

Basic JUnit 5 Test

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

class CalculatorTest {

    @Test
    void shouldAddTwoNumbers() {
        Calculator calculator = new Calculator();

        int result = calculator.add(2, 3);

        assertEquals(5, result);
    }
}

Assertion Examples

assertEquals(expected, actual);
assertNotEquals(expected, actual);
assertTrue(condition);
assertFalse(condition);
assertNull(value);
assertNotNull(value);
assertThrows(IllegalArgumentException.class, () -> service.process(null));
assertAll(
    () -> assertEquals("John", user.getFirstName()),
    () -> assertEquals("Doe", user.getLastName())
);

Parameterized Test

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;

import static org.junit.jupiter.api.Assertions.assertEquals;

class DiscountServiceTest {

    @ParameterizedTest
    @CsvSource({
        "100, 10, 90",
        "200, 25, 150",
        "50, 0, 50"
    })
    void shouldApplyDiscount(int price, int discountPercent, int expected) {
        DiscountService service = new DiscountService();

        int actual = service.applyDiscount(price, discountPercent);

        assertEquals(expected, actual);
    }
}

JUnit 5 Best Practices

  • Test method names should describe expected behavior.
  • Prefer one behavioral reason for failure per test.
  • Use assertThrows for exception scenarios.
  • Avoid testing private methods directly.
  • Keep unit tests independent from Spring when Spring is not required.
  • Use parameterized tests when the same logic must be validated with multiple inputs.

3. Mockito

Mockito is used to create test doubles for dependencies. It is useful when testing a class in isolation.

Common Mockito Concepts

ConceptMeaning
MockFake object with programmable behavior
StubPredefined behavior for a mock
VerifyCheck whether a method was called
SpyPartial mock around a real object
Argument matcherFlexible way to match method arguments

Mockito with JUnit 5

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class OrderServiceTest {

    @Mock
    private OrderRepository orderRepository;

    @InjectMocks
    private OrderService orderService;

    @Test
    void shouldReturnOrderTotal() {
        when(orderRepository.findTotalByOrderId(1L)).thenReturn(500);

        int total = orderService.getOrderTotal(1L);

        assertEquals(500, total);
        verify(orderRepository).findTotalByOrderId(1L);
    }
}

Common Mockito Methods

when(repository.findById(1L)).thenReturn(Optional.of(entity));
when(service.process()).thenThrow(new RuntimeException("failed"));

verify(repository).save(entity);
verify(repository, times(1)).save(entity);
verify(repository, never()).delete(entity);
verifyNoMoreInteractions(repository);

any();
anyString();
anyLong();
eq("ACTIVE");

@Mock vs @MockBean

AnnotationUsed InPurpose
@MockPlain unit testsCreates a Mockito mock outside the Spring context
@MockBeanSpring Boot testsAdds or replaces a bean in the Spring application context

Mockito Best Practices

  • Use Mockito for dependencies, not for the class under test.
  • Avoid mocking value objects, DTOs, entities, and simple data structures.
  • Prefer verifying important side effects, not every internal method call.
  • Do not overuse spies; they often indicate poor test design.
  • Keep stubbing minimal and relevant to the test scenario.

4. @SpringBootTest

@SpringBootTest loads the full Spring application context. It is used for integration tests where multiple layers must work together.

When to Use @SpringBootTest

Use it when testing:

  • Application startup and configuration.
  • Service integration with repositories.
  • Multiple beans working together.
  • Real Spring configuration, filters, aspects, events, or transactions.
  • Integration with external infrastructure through Testcontainers.

Avoid it for simple unit tests because it is slower than focused tests.

Basic Example

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import static org.junit.jupiter.api.Assertions.assertNotNull;

@SpringBootTest
class ApplicationContextTest {

    @Autowired
    private OrderService orderService;

    @Test
    void contextLoads() {
        assertNotNull(orderService);
    }
}

Web Environment Options

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
OptionMeaning
MOCKCreates a mock servlet environment; does not start a real server
RANDOM_PORTStarts the embedded server on a random port
DEFINED_PORTStarts the embedded server on the configured port
NONELoads application context without web environment

@SpringBootTest with MockMvc

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@SpringBootTest
@AutoConfigureMockMvc
class OrderIntegrationTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    void shouldGetOrders() throws Exception {
        mockMvc.perform(get("/orders"))
            .andExpect(status().isOk());
    }
}

5. @WebMvcTest

@WebMvcTest is a Spring MVC slice test. It loads only web-layer components, not the full application context.

It usually loads:

  • Controllers.
  • Controller advice.
  • JSON serialization components.
  • Spring MVC infrastructure.
  • Filters, depending on configuration.

It does not load:

  • Service beans.
  • Repository beans.
  • Full application configuration.

Basic @WebMvcTest

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;

import java.util.List;

import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@WebMvcTest(OrderController.class)
class OrderControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private OrderService orderService;

    @Test
    void shouldReturnOrders() throws Exception {
        when(orderService.findAll()).thenReturn(List.of(new OrderDto(1L, "NEW")));

        mockMvc.perform(get("/orders"))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$[0].id").value(1))
            .andExpect(jsonPath("$[0].status").value("NEW"));
    }
}

When to Use @WebMvcTest

Use it to test:

  • Request mappings.
  • HTTP status codes.
  • Request validation.
  • JSON request and response structure.
  • Controller exception handling.
  • Security behavior at the MVC layer.

Common Issue

If the controller depends on a service, provide it using @MockBean.

@MockBean
private UserService userService;

Without this, the test may fail because @WebMvcTest does not load service-layer beans.

6. @DataJpaTest

@DataJpaTest is a persistence slice test. It focuses on JPA repositories and entity mapping.

It usually configures:

  • JPA repositories.
  • EntityManager.
  • Hibernate.
  • DataSource.
  • Transaction rollback after each test.

By default, Spring Boot often replaces the real database with an embedded database if one is available.

Basic @DataJpaTest

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;

import java.util.Optional;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

@DataJpaTest
class OrderRepositoryTest {

    @Autowired
    private OrderRepository orderRepository;

    @Test
    void shouldFindOrderByStatus() {
        Order order = new Order();
        order.setStatus("NEW");
        orderRepository.save(order);

        Optional<Order> result = orderRepository.findFirstByStatus("NEW");

        assertTrue(result.isPresent());
        assertEquals("NEW", result.get().getStatus());
    }
}

Using TestEntityManager

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;

import static org.junit.jupiter.api.Assertions.assertEquals;

@DataJpaTest
class CustomerRepositoryTest {

    @Autowired
    private TestEntityManager entityManager;

    @Autowired
    private CustomerRepository customerRepository;

    @Test
    void shouldFindByEmail() {
        Customer customer = new Customer();
        customer.setEmail("a@example.com");
        entityManager.persistAndFlush(customer);

        Customer result = customerRepository.findByEmail("a@example.com").orElseThrow();

        assertEquals("a@example.com", result.getEmail());
    }
}

Using Real Database with @DataJpaTest

import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;

@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class OrderRepositoryRealDatabaseTest {
}

@DataJpaTest Best Practices

  • Use it for repository methods, JPQL queries, native queries, and entity mappings.
  • Verify database constraints where relevant.
  • Prefer Testcontainers when database-specific behavior matters.
  • Remember that tests are transactional and usually roll back after each test.

7. MockMvc

MockMvc tests Spring MVC applications without starting a real HTTP server.

It can be used with:

  • @WebMvcTest
  • @SpringBootTest plus @AutoConfigureMockMvc
  • Standalone controller setup

Common MockMvc Request Methods

mockMvc.perform(get("/api/users"));
mockMvc.perform(post("/api/users"));
mockMvc.perform(put("/api/users/1"));
mockMvc.perform(patch("/api/users/1"));
mockMvc.perform(delete("/api/users/1"));

POST JSON Example

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@WebMvcTest(UserController.class)
class UserControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    void shouldCreateUser() throws Exception {
        String request = """
            {
              "name": "John",
              "email": "john@example.com"
            }
            """;

        mockMvc.perform(post("/users")
                .contentType(MediaType.APPLICATION_JSON)
                .content(request))
            .andExpect(status().isCreated())
            .andExpect(header().exists("Location"));
    }
}

Common MockMvc Result Matchers

andExpect(status().isOk());
andExpect(status().isCreated());
andExpect(status().isBadRequest());
andExpect(status().isNotFound());

andExpect(content().contentType(MediaType.APPLICATION_JSON));
andExpect(jsonPath("$.id").value(1));
andExpect(jsonPath("$.name").value("John"));
andExpect(header().string("Location", "/users/1"));

Testing Validation Errors

mockMvc.perform(post("/users")
        .contentType(MediaType.APPLICATION_JSON)
        .content("""
            {
              "name": "",
              "email": "invalid"
            }
            """))
    .andExpect(status().isBadRequest())
    .andExpect(jsonPath("$.errors").exists());

MockMvc Best Practices

  • Use @WebMvcTest for fast controller tests.
  • Use @SpringBootTest with @AutoConfigureMockMvc when filters, security, or full wiring matters.
  • Assert status, content type, headers, and important response fields.
  • Avoid asserting the entire JSON response unless the full contract matters.

8. Testcontainers

Testcontainers provides lightweight, disposable Docker containers for integration tests.

It is commonly used for:

  • PostgreSQL.
  • MySQL.
  • MongoDB.
  • Kafka.
  • Redis.
  • RabbitMQ.
  • LocalStack.

Why Use Testcontainers

Embedded databases are fast, but they may not behave exactly like production databases. Testcontainers helps test against real infrastructure.

Example: PostgreSQL-specific SQL, JSONB columns, database indexes, case sensitivity, extensions, and transaction behavior are better tested with real PostgreSQL than with H2.

Basic PostgreSQL Testcontainer

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

import static org.junit.jupiter.api.Assertions.assertTrue;

@Testcontainers
@SpringBootTest
class OrderServiceIntegrationTest {

    @Container
    @ServiceConnection
    static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine");

    @Test
    void shouldUsePostgresContainer() {
        assertTrue(postgres.isRunning());
    }
}

Dynamic Property Registration

For Spring Boot versions or setups where @ServiceConnection is not used:

import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

@Testcontainers
class DatabaseIntegrationTest {

    @Container
    static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine");

    @DynamicPropertySource
    static void configureProperties(DynamicPropertyRegistry registry) {
        registry.add("spring.datasource.url", postgres::getJdbcUrl);
        registry.add("spring.datasource.username", postgres::getUsername);
        registry.add("spring.datasource.password", postgres::getPassword);
    }
}

Testcontainers with @DataJpaTest

import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

@Testcontainers
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class OrderRepositoryPostgresTest {

    @Container
    @ServiceConnection
    static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine");
}

Testcontainers Best Practices

  • Use Testcontainers when production-like infrastructure behavior matters.
  • Keep containers static when possible to avoid restarting them for every test method.
  • Prefer lightweight images such as Alpine variants when appropriate.
  • Avoid using Testcontainers for every unit test; reserve it for integration tests.
  • Ensure Docker is available in the test environment.

9. Choosing the Right Spring Test Annotation

RequirementRecommended Approach
Test one class with mocked dependenciesJUnit 5 plus Mockito
Test controller request and response behavior@WebMvcTest plus MockMvc
Test repository query or entity mapping@DataJpaTest
Test several Spring beans together@SpringBootTest
Test MVC behavior with full application wiring@SpringBootTest plus @AutoConfigureMockMvc
Test real database behaviorTestcontainers plus @DataJpaTest or @SpringBootTest
Test external service integrationTestcontainers, WireMock, or mocked client depending on scope

10. Common Test Dependencies

Maven

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>junit-jupiter</artifactId>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>postgresql</artifactId>
    <scope>test</scope>
</dependency>

Gradle

testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.testcontainers:junit-jupiter'
testImplementation 'org.testcontainers:postgresql'

11. Interview Questions

Basic Questions

  1. What is the difference between unit testing and integration testing?
  2. What are the main components of JUnit 5?
  3. What is the purpose of @Test in JUnit 5?
  4. What is the difference between @BeforeEach and @BeforeAll?
  5. What is the use of assertThrows?
  6. Why should unit tests be independent and repeatable?
  7. What is Mockito used for?
  8. What is the difference between a mock and a spy?
  9. What is the difference between stubbing and verification in Mockito?
  10. What is the difference between @Mock and @InjectMocks?

Spring Boot Testing Questions

  1. What does @SpringBootTest do?
  2. Why is @SpringBootTest slower than slice tests?
  3. What are the different webEnvironment options in @SpringBootTest?
  4. What is the purpose of @AutoConfigureMockMvc?
  5. What is @WebMvcTest used for?
  6. Which beans are loaded by @WebMvcTest?
  7. Why do we often use @MockBean with @WebMvcTest?
  8. What is @DataJpaTest used for?
  9. Does @DataJpaTest load service beans?
  10. Why does @DataJpaTest usually roll back transactions after each test?

MockMvc Questions

  1. What is MockMvc?
  2. Does MockMvc start a real HTTP server?
  3. How do you test a POST request with JSON using MockMvc?
  4. How do you verify HTTP status and response body using MockMvc?
  5. When should you use MockMvc with @WebMvcTest?
  6. When should you use MockMvc with @SpringBootTest?
  7. How do you test validation errors using MockMvc?
  8. How do you test controller advice with MockMvc?

Testcontainers Questions

  1. What problem does Testcontainers solve?
  2. Why might H2 be insufficient for repository integration tests?
  3. How does Testcontainers help with production-like testing?
  4. What is the purpose of @Testcontainers?
  5. What is the purpose of @Container?
  6. What is @DynamicPropertySource used for?
  7. What is @ServiceConnection in Spring Boot tests?
  8. How can Testcontainers be used with @DataJpaTest?
  9. What are the trade-offs of using Testcontainers?
  10. Why should containers often be declared as static fields?

Scenario-Based Questions

  1. You need to test a service method that depends on a repository. Which tools would you use?
  2. You need to test only controller validation and JSON response structure. Which annotation is best?
  3. You need to test a custom Spring Data JPA query. Which annotation is best?
  4. You need to test that the full application context starts successfully. Which annotation is best?
  5. You need to test PostgreSQL-specific behavior. Which tool should you use?
  6. A @WebMvcTest fails because a service bean is missing. How do you fix it?
  7. A repository test passes on H2 but fails on PostgreSQL. What should you change?
  8. A test using @SpringBootTest is slow. How can you improve it?
  9. You need to verify that a dependency method was called once. How do you do that in Mockito?
  10. You need to verify that invalid input causes an exception. Which JUnit assertion should you use?

12. Cheat Sheet

JUnit 5

NeedUse
Mark test method@Test
Run setup before each test@BeforeEach
Run setup once before all tests@BeforeAll
Check equalityassertEquals(expected, actual)
Check exceptionassertThrows(Exception.class, executable)
Group assertionsassertAll(...)
Run same test with multiple values@ParameterizedTest

Mockito

NeedUse
Create mock@Mock
Inject mocks into tested class@InjectMocks
Enable Mockito in JUnit 5@ExtendWith(MockitoExtension.class)
Stub methodwhen(mock.method()).thenReturn(value)
Verify method callverify(mock).method()
Verify call countverify(mock, times(1)).method()
Match any stringanyString()
Match exact value with matcherseq(value)

Spring Boot Test Annotations

AnnotationScopeTypical Use
@SpringBootTestFull application contextIntegration tests
@WebMvcTestMVC sliceController tests
@DataJpaTestJPA sliceRepository tests
@AutoConfigureMockMvcAdds MockMvcMVC testing with full context
@MockBeanSpring context mockReplace a bean in Spring tests
@AutoConfigureTestDatabaseTest database configControl embedded database replacement

MockMvc

NeedUse
GET requestmockMvc.perform(get("/path"))
POST JSONmockMvc.perform(post("/path").contentType(APPLICATION_JSON).content(json))
Check status.andExpect(status().isOk())
Check JSON field.andExpect(jsonPath("$.field").value(value))
Check header.andExpect(header().string("Name", "value"))
Check content type.andExpect(content().contentType(APPLICATION_JSON))

Testcontainers

NeedUse
Enable Testcontainers extension@Testcontainers
Declare container@Container
PostgreSQL containerPostgreSQLContainer<?>
Register Spring properties manually@DynamicPropertySource
Auto-connect container in Spring Boot@ServiceConnection
Prevent test DB replacement@AutoConfigureTestDatabase(replace = NONE)

Quick Decision Guide

If You Need To TestUse
Pure business logicJUnit 5
Business logic with mocked dependencyJUnit 5 plus Mockito
Controller mapping and validation@WebMvcTest plus MockMvc
Repository query@DataJpaTest
Repository query against real database@DataJpaTest plus Testcontainers
Full application wiring@SpringBootTest
Full MVC request flow without real server@SpringBootTest plus @AutoConfigureMockMvc
Production-like external infrastructureTestcontainers

13. Key Takeaways

  • Prefer fast unit tests for business logic.
  • Use Mockito to isolate a class from its dependencies.
  • Use Spring slice tests when only one layer needs to be tested.
  • Use @SpringBootTest only when full application wiring is required.
  • Use MockMvc for testing Spring MVC request and response behavior.
  • Use Testcontainers when real infrastructure behavior matters.
  • Choose the smallest test scope that gives confidence.