CtrlK
BlogDocsLog inGet started
Tessl Logo

giuseppe-trisciuoglio/developer-kit

Comprehensive developer toolkit providing reusable skills for Java/Spring Boot, TypeScript/NestJS/React/Next.js, Python, PHP, AWS CloudFormation, AI/RAG, DevOps, and more.

89

Quality

89%

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Risky

Do not use without reviewing

Overview
Quality
Evals
Security
Files

advanced-patterns.mdplugins/developer-kit-java/skills/unit-test-bean-validation/references/

Advanced Validation Patterns Reference

Validation Groups

Defining Groups

public interface CreateValidation {}
public interface UpdateValidation {}
public interface AdminValidation {}

Using Groups in DTOs

class UserDto {
  @NotNull(groups = CreateValidation.class)
  private String name;

  @Min(value = 0, groups = {CreateValidation.class, UpdateValidation.class})
  private int age;
}

Testing Groups

class ValidationGroupsTest extends BaseValidationTest {

  @Test
  void shouldRequireNameOnlyDuringCreation() {
    UserDto user = new UserDto(null, 25);

    Set<ConstraintViolation<UserDto>> violations =
        validator.validate(user, CreateValidation.class);

    assertThat(violations)
      .extracting(ConstraintViolation::getPropertyPath)
      .extracting(Path::toString)
      .contains("name");
  }

  @Test
  void shouldAllowNullNameDuringUpdate() {
    UserDto user = new UserDto(null, 25);
    assertThat(validator.validate(user, UpdateValidation.class)).isEmpty();
  }

  @Test
  void shouldValidateMultipleGroups() {
    UserDto user = new UserDto("Alice", -5);
    Set<ConstraintViolation<UserDto>> violations =
        validator.validate(user, CreateValidation.class, UpdateValidation.class);
    assertThat(violations).isNotEmpty();
  }
}

Parameterized Tests

Email Validation

class EmailValidationTest extends BaseValidationTest {

  @ParameterizedTest
  @ValueSource(strings = {
    "user@example.com",
    "john.doe+tag@example.co.uk",
    "admin@subdomain.example.com"
  })
  void shouldAcceptValidEmails(String email) {
    UserDto user = new UserDto("Alice", email);
    assertThat(validator.validate(user)).isEmpty();
  }

  @ParameterizedTest
  @ValueSource(strings = {
    "invalid-email", "user@", "@example.com", "user name@example.com"
  })
  void shouldRejectInvalidEmails(String email) {
    UserDto user = new UserDto("Alice", email);
    assertThat(validator.validate(user)).isNotEmpty();
  }
}

Multiple Parameters

class RangeValidationTest extends BaseValidationTest {

  @ParameterizedTest
  @CsvSource({
    "0, 100, true",
    "-1, 100, false",
    "0, 0, false",
    "50, 100, true"
  })
  void shouldValidateRange(int min, int max, boolean shouldPass) {
    RangeDto dto = new RangeDto(min, max);
    var violations = validator.validate(dto);
    assertThat(violations.isEmpty()).isEqualTo(shouldPass);
  }
}

Debugging Failed Tests

When Tests Fail

  1. Check violation count: assertThat(violations).hasSize(n)
  2. Inspect property path: violation.getPropertyPath().toString()
  3. Verify message: violation.getMessage()
  4. Check invalid value: violation.getInvalidValue()
@Test
void debugFailedValidation() {
  UserDto user = new UserDto("", "invalid");

  Set<ConstraintViolation<UserDto>> violations = validator.validate(user);

  // Debug output
  violations.forEach(v -> System.out.println(
    v.getPropertyPath() + ": " + v.getMessage()
  ));

  assertThat(violations).hasSize(2);
}

Common Issues

IssueCauseSolution
ConstraintViolation nullObject is valid or constraint doesn't fireCheck annotation parameters
Wrong property pathWrong field annotatedVerify @Constraint(validatedBy=)
Null passes validationConstraint allows nullAdd @NotNull
Multiple violationsMultiple constraints failUse hasSize() to verify count

plugins

developer-kit-java

skills

unit-test-bean-validation

README.md

CHANGELOG.md

context7.json

CONTRIBUTING.md

README_CN.md

README_ES.md

README_IT.md

README.md

tessl.json

tile.json