# (DD47) Business Logic — PetTypeFormatterTests.shouldThrowParseException() [7 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `org.springframework.samples.petclinic.owner.PetTypeFormatterTests` |
| Layer | Utility / Test |
| Module | `owner` (Package: `org.springframework.samples.petclinic.owner`) |

## 1. Role

### PetTypeFormatterTests.shouldThrowParseException()

This test method verifies the negative-path behavior of the PetType formatting workflow in the owner module. Its business purpose is to confirm that the formatter rejects an unknown pet type label and surfaces a parsing failure rather than silently accepting invalid master-data values.

The method first prepares a controlled reference set of pet types by stubbing the repository call that supplies the available lookup values. It then exercises the formatter with the business input value `"Fish"`, which is intentionally absent from the fixture data, to confirm that the formatter enforces lookup-based validation. In system terms, this protects screens that bind pet type selections from accepting unsupported values and ensures consistent data integrity against the reference list. The method implements a simple test-driven verification pattern: arrange test data, invoke the formatter, and assert that the expected exception is thrown.

There are no conditional branches inside the test itself, but it is validating a branched decision inside the production formatter: if the input text matches an existing pet type name, the formatter returns the corresponding domain object; otherwise, it throws a `ParseException`. This method specifically covers the failure branch and confirms the error-handling contract for unmatched values.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START["shouldThrowParseException()"]
    STUB["Stub PetTypeRepository.findPetTypes() to return fixture data"]
    CALL_FIXTURE["makePetTypes()"]
    ASSERT_CALL["Assert ParseException when petTypeFormatter.parse(\"Fish\", Locale.ENGLISH) is invoked"]
    PARSE_CALL["petTypeFormatter.parse(\"Fish\", Locale.ENGLISH)"]
    READ_TYPES["PetTypeRepository.findPetTypes()"]
    ITERATE["Iterate through available PetType entries"]
    COMPARE["type.getName() equals input text?"]
    MATCH["Return matching PetType"]
    NO_MATCH["No matching pet type found"]
    THROW["Throw ParseException - type not found: Fish"]
    END_NODE["Test completes"]

    START --> STUB
    STUB --> CALL_FIXTURE
    STUB --> ASSERT_CALL
    ASSERT_CALL --> PARSE_CALL
    PARSE_CALL --> READ_TYPES
    READ_TYPES --> ITERATE
    ITERATE --> COMPARE
    COMPARE --> MATCH
    COMPARE --> NO_MATCH
    NO_MATCH --> THROW
    MATCH --> END_NODE
    THROW --> END_NODE
```

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| - | (none) | - | - |

External state read by the method:
- `types` — mocked `PetTypeRepository` used to provide the list of reference pet types.
- `petTypeFormatter` — formatter under test, which applies lookup-based parsing rules.
- `Locale.ENGLISH` — locale passed into the formatter call, present for API completeness but not used for branch selection in this test.
- `makePetTypes()` — local test fixture helper that supplies the available master-data set.

## 4. CRUD Operations / Called Services

### Pre-computed evidence from code analysis graph:

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| - | `PetTypeFormatterTests.makePetTypes` | PetTypeFormatterTests | - | Calls `makePetTypes` in `PetTypeFormatterTests` |

Analyze all method calls within this method and classify each as a CRUD operation.
Use the pre-computed evidence above. If SC Code or Entity/DB is missing, try to infer from:
- The **SC Code** (Service Component code, e.g., `EKK0361A010SC`, `EKK1081D010CBS`) — look at the class name of the called method or its containing class.
- The **Entity/DB tables** — search for table name constants (often `KK_T_*` pattern), SQL references, or entity names in the called method's source code.

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `makePetTypes` | PetTypeFormatterTests | Test fixture collection | Builds the reference pet type list used as the repository return value for the parse failure scenario |
| R | `types.findPetTypes()` | PetTypeRepository | `PetType` master data | Reads the available pet type reference set to support formatter parsing |
| R | `petTypeFormatter.parse(String, Locale)` | PetTypeFormatter | `PetType` master data | Attempts to resolve the input label against the reference pet type list and throws when no match exists |

## 5. Dependency Trace

Trace who calls this method and what this method ultimately calls.
Use the pre-computed evidence and caller search results from Step 2 above.

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | JUnit 5 `@Test` runner | `JUnit 5 test engine` -> `PetTypeFormatterTests.shouldThrowParseException()` | `petTypeFormatter.parse(String, Locale) [R] PetType` |

**Notes:**
- This method is an automated unit test and is not invoked by a business screen or batch entry point.
- The only executed business dependency is the formatter parse path, which reads pet type reference data and raises `ParseException` for an unmatched value.

## 6. Per-Branch Detail Blocks

**Block 1** — **SET** `(test fixture preparation)` (L71)

> Prepare a controlled lookup set so the parse failure can be tested deterministically.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `makePetTypes()` // create the in-memory pet type reference data |
| 2 | CALL | `given(types.findPetTypes()).willReturn(makePetTypes());` // stub repository lookup with fixture data |

**Block 2** — **TRY-CATCH** `(assert ParseException on unmatched input)` (L72-L75)

> Execute the formatter with a label that is not present in the lookup list and verify that the parse contract fails.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `Assertions.assertThrows(ParseException.class, () -> { ... });` // verify the exception contract |
| 2 | CALL | `petTypeFormatter.parse("Fish", Locale.ENGLISH);` // attempt to resolve an unsupported pet type label |

**Block 3** — **RETURN** `(test method completion)` (L76)

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `}` // end of test method |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| PetType | Domain object | Reference data entity representing a category of pet such as Dog or Bird |
| PetTypeRepository | Repository | Data access component that provides the available pet type master-data list |
| Formatter | Technical term | Spring MVC contract for converting between text input and domain objects |
| parse | Business term | Conversion step that resolves a user-entered label into the corresponding domain reference object |
| ParseException | Exception | Error thrown when the supplied text does not match any available reference value |
| Locale | Technical term | Language and regional context supplied to formatting APIs |
| `types` | Field | Mocked repository dependency that supplies the pet type lookup set during the test |
| `petTypeFormatter` | Field | Formatter under test that performs the text-to-domain lookup |
| `makePetTypes` | Test helper | Fixture builder that creates sample pet type records for the repository stub |
| `Fish` | Test input | Deliberately invalid pet type label used to verify the failure branch |
| `Dog` | Sample value | Typical valid pet type example included in the fixture set |
| `Bird` | Sample value | Typical valid pet type example included in the fixture set |
| JUnit 5 | Test framework | Unit testing framework used to execute the method as an automated regression check |
| `assertThrows` | Assertion API | Test assertion that verifies an exception is raised for invalid input |
