@ngxtm/devkit 3.3.0 → 3.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/index.js +59 -13
- package/cli/rules.js +248 -0
- package/package.json +2 -1
- package/rules/README.md +141 -0
- package/rules/dart/best-practices/SKILL.md +23 -0
- package/rules/dart/language/SKILL.md +52 -0
- package/rules/dart/tooling/SKILL.md +43 -0
- package/rules/dotnet/aspnet-core/SKILL.md +92 -0
- package/rules/dotnet/aspnet-core/references/REFERENCE.md +335 -0
- package/rules/dotnet/best-practices/SKILL.md +101 -0
- package/rules/dotnet/best-practices/references/REFERENCE.md +256 -0
- package/rules/dotnet/blazor/SKILL.md +146 -0
- package/rules/dotnet/blazor/references/REFERENCE.md +392 -0
- package/rules/dotnet/language/SKILL.md +82 -0
- package/rules/dotnet/language/references/REFERENCE.md +222 -0
- package/rules/dotnet/patterns.rule.md +388 -0
- package/rules/dotnet/razor-pages/SKILL.md +124 -0
- package/rules/dotnet/razor-pages/references/REFERENCE.md +321 -0
- package/rules/dotnet/security/SKILL.md +89 -0
- package/rules/dotnet/security/references/REFERENCE.md +295 -0
- package/rules/dotnet/tooling/SKILL.md +92 -0
- package/rules/dotnet/tooling/references/REFERENCE.md +300 -0
- package/rules/flutter/auto-route-navigation/SKILL.md +43 -0
- package/rules/flutter/auto-route-navigation/references/REFERENCE.md +19 -0
- package/rules/flutter/auto-route-navigation/references/router-config.md +62 -0
- package/rules/flutter/bloc-state-management/SKILL.md +64 -0
- package/rules/flutter/bloc-state-management/references/REFERENCE.md +20 -0
- package/rules/flutter/bloc-state-management/references/auth-bloc-example.md +52 -0
- package/rules/flutter/bloc-state-management/references/equatable-usage.md +56 -0
- package/rules/flutter/bloc-state-management/references/property-based-state.md +68 -0
- package/rules/flutter/bloc.rule.md +76 -0
- package/rules/flutter/cicd/SKILL.md +48 -0
- package/rules/flutter/cicd/references/advanced-workflow.md +66 -0
- package/rules/flutter/cicd/references/fastlane.md +139 -0
- package/rules/flutter/cicd/references/github-actions.md +59 -0
- package/rules/flutter/dependency-injection/SKILL.md +42 -0
- package/rules/flutter/dependency-injection/references/REFERENCE.md +15 -0
- package/rules/flutter/dependency-injection/references/modules.md +37 -0
- package/rules/flutter/error-handling/SKILL.md +32 -0
- package/rules/flutter/error-handling/references/REFERENCE.md +19 -0
- package/rules/flutter/error-handling/references/error-mapping.md +31 -0
- package/rules/flutter/feature-based-clean-architecture/SKILL.md +46 -0
- package/rules/flutter/feature-based-clean-architecture/references/REFERENCE.md +14 -0
- package/rules/flutter/feature-based-clean-architecture/references/folder-structure.md +36 -0
- package/rules/flutter/getx-navigation/SKILL.md +70 -0
- package/rules/flutter/getx-navigation/references/app-pages.md +40 -0
- package/rules/flutter/getx-navigation/references/middleware-example.md +29 -0
- package/rules/flutter/getx-state-management/SKILL.md +76 -0
- package/rules/flutter/getx-state-management/references/binding-example.md +32 -0
- package/rules/flutter/getx-state-management/references/reactive-vs-simple.md +39 -0
- package/rules/flutter/go-router-navigation/SKILL.md +57 -0
- package/rules/flutter/idiomatic-flutter/SKILL.md +20 -0
- package/rules/flutter/layer-based-clean-architecture/SKILL.md +50 -0
- package/rules/flutter/layer-based-clean-architecture/references/REFERENCE.md +60 -0
- package/rules/flutter/layer-based-clean-architecture/references/repository-mapping.md +50 -0
- package/rules/flutter/localization/SKILL.md +50 -0
- package/rules/flutter/localization/references/REFERENCE.md +48 -0
- package/rules/flutter/localization/references/sheet-loader.md +33 -0
- package/rules/flutter/navigator-v1-navigation/SKILL.md +71 -0
- package/rules/flutter/navigator-v1-navigation/references/on-generate-route.md +48 -0
- package/rules/flutter/performance/SKILL.md +24 -0
- package/rules/flutter/retrofit-networking/SKILL.md +51 -0
- package/rules/flutter/retrofit-networking/references/REFERENCE.md +19 -0
- package/rules/flutter/retrofit-networking/references/token-refresh.md +40 -0
- package/rules/flutter/riverpod-state-management/SKILL.md +53 -0
- package/rules/flutter/riverpod-state-management/references/architecture.md +124 -0
- package/rules/flutter/riverpod-state-management/references/best-practices.md +89 -0
- package/rules/flutter/riverpod-state-management/references/testing.md +73 -0
- package/rules/flutter/riverpod.rule.md +78 -0
- package/rules/flutter/security/SKILL.md +33 -0
- package/rules/flutter/security/references/REFERENCE.md +15 -0
- package/rules/flutter/security/references/network-security.md +28 -0
- package/rules/flutter/testing/SKILL.md +44 -0
- package/rules/flutter/testing/references/REFERENCE.md +21 -0
- package/rules/flutter/testing/references/bloc-testing.md +38 -0
- package/rules/flutter/testing/references/integration-testing.md +128 -0
- package/rules/flutter/testing/references/robot-pattern.md +82 -0
- package/rules/flutter/testing/references/unit-testing.md +130 -0
- package/rules/flutter/testing/references/widget-testing.md +120 -0
- package/rules/flutter/widgets/SKILL.md +37 -0
- package/rules/golang/chi-router/SKILL.md +219 -0
- package/rules/golang/chi-router/references/REFERENCE.md +13 -0
- package/rules/golang/chi-router/references/routing-patterns.md +205 -0
- package/rules/golang/cobra-cli/SKILL.md +227 -0
- package/rules/golang/cobra-cli/references/REFERENCE.md +13 -0
- package/rules/golang/cobra-cli/references/command-patterns.md +224 -0
- package/rules/golang/core/SKILL.md +210 -0
- package/rules/golang/core/references/REFERENCE.md +14 -0
- package/rules/golang/core/references/concurrency-patterns.md +114 -0
- package/rules/golang/core/references/error-handling.md +87 -0
- package/rules/golang/echo-framework/SKILL.md +215 -0
- package/rules/golang/echo-framework/references/REFERENCE.md +14 -0
- package/rules/golang/echo-framework/references/middleware-patterns.md +141 -0
- package/rules/golang/echo-framework/references/routing-patterns.md +140 -0
- package/rules/golang/ent-orm/SKILL.md +239 -0
- package/rules/golang/ent-orm/references/REFERENCE.md +13 -0
- package/rules/golang/ent-orm/references/schema-patterns.md +255 -0
- package/rules/golang/fiber-framework/SKILL.md +196 -0
- package/rules/golang/fiber-framework/references/REFERENCE.md +13 -0
- package/rules/golang/fiber-framework/references/routing-patterns.md +191 -0
- package/rules/golang/gin-framework/SKILL.md +205 -0
- package/rules/golang/gin-framework/references/REFERENCE.md +14 -0
- package/rules/golang/gin-framework/references/middleware-patterns.md +119 -0
- package/rules/golang/gorm-orm/SKILL.md +196 -0
- package/rules/golang/gorm-orm/references/REFERENCE.md +14 -0
- package/rules/golang/gorm-orm/references/model-definitions.md +167 -0
- package/rules/golang/gorm-orm/references/query-patterns.md +161 -0
- package/rules/golang/grpc/SKILL.md +231 -0
- package/rules/golang/grpc/references/REFERENCE.md +13 -0
- package/rules/golang/grpc/references/service-patterns.md +276 -0
- package/rules/golang/testify/SKILL.md +239 -0
- package/rules/golang/testify/references/REFERENCE.md +13 -0
- package/rules/golang/testify/references/assert-patterns.md +170 -0
- package/rules/golang/validator/SKILL.md +234 -0
- package/rules/golang/validator/references/REFERENCE.md +13 -0
- package/rules/golang/validator/references/validation-tags.md +211 -0
- package/rules/golang/viper-config/SKILL.md +244 -0
- package/rules/golang/viper-config/references/REFERENCE.md +13 -0
- package/rules/golang/viper-config/references/config-loading.md +181 -0
- package/rules/golang/wire-di/SKILL.md +243 -0
- package/rules/golang/wire-di/references/REFERENCE.md +13 -0
- package/rules/golang/wire-di/references/provider-patterns.md +193 -0
- package/rules/golang/zap-logging/SKILL.md +203 -0
- package/rules/golang/zap-logging/references/REFERENCE.md +13 -0
- package/rules/golang/zap-logging/references/logger-config.md +165 -0
- package/rules/java/build-gradle/SKILL.md +92 -0
- package/rules/java/build-gradle/references/REFERENCE.md +14 -0
- package/rules/java/build-gradle/references/kotlin-dsl.md +118 -0
- package/rules/java/build-gradle/references/task-configuration.md +132 -0
- package/rules/java/build-maven/SKILL.md +86 -0
- package/rules/java/build-maven/references/REFERENCE.md +14 -0
- package/rules/java/build-maven/references/dependency-management.md +111 -0
- package/rules/java/build-maven/references/lifecycle-phases.md +114 -0
- package/rules/java/graalvm-native/SKILL.md +105 -0
- package/rules/java/graalvm-native/references/REFERENCE.md +12 -0
- package/rules/java/java-collections-streams/SKILL.md +148 -0
- package/rules/java/java-collections-streams/references/REFERENCE.md +15 -0
- package/rules/java/java-collections-streams/references/collectors-patterns.md +178 -0
- package/rules/java/java-collections-streams/references/stream-pipelines.md +165 -0
- package/rules/java/java-concurrency/SKILL.md +187 -0
- package/rules/java/java-concurrency/references/REFERENCE.md +17 -0
- package/rules/java/java-concurrency/references/completable-future.md +165 -0
- package/rules/java/java-concurrency/references/executor-patterns.md +176 -0
- package/rules/java/java-concurrency/references/virtual-threads.md +190 -0
- package/rules/java/java-core-language/SKILL.md +121 -0
- package/rules/java/java-core-language/references/REFERENCE.md +15 -0
- package/rules/java/java-core-language/references/jvm-memory-model.md +160 -0
- package/rules/java/java-core-language/references/modern-java-features.md +168 -0
- package/rules/java/java-project-structure/SKILL.md +195 -0
- package/rules/java/java-project-structure/references/REFERENCE.md +15 -0
- package/rules/java/java-project-structure/references/maven-project-layout.md +199 -0
- package/rules/java/java-project-structure/references/module-system.md +159 -0
- package/rules/java/micronaut-core/SKILL.md +99 -0
- package/rules/java/micronaut-core/references/REFERENCE.md +12 -0
- package/rules/java/micronaut-reactive/SKILL.md +68 -0
- package/rules/java/micronaut-reactive/references/REFERENCE.md +12 -0
- package/rules/java/quarkus-core/SKILL.md +85 -0
- package/rules/java/quarkus-core/references/REFERENCE.md +12 -0
- package/rules/java/quarkus-reactive/SKILL.md +67 -0
- package/rules/java/quarkus-reactive/references/REFERENCE.md +12 -0
- package/rules/java/spring-batch/SKILL.md +102 -0
- package/rules/java/spring-batch/references/REFERENCE.md +12 -0
- package/rules/java/spring-boot-architecture/SKILL.md +206 -0
- package/rules/java/spring-boot-architecture/references/REFERENCE.md +15 -0
- package/rules/java/spring-boot-architecture/references/auto-configuration.md +158 -0
- package/rules/java/spring-boot-architecture/references/configuration-properties.md +202 -0
- package/rules/java/spring-boot-web/SKILL.md +217 -0
- package/rules/java/spring-boot-web/references/REFERENCE.md +17 -0
- package/rules/java/spring-cloud/SKILL.md +109 -0
- package/rules/java/spring-cloud/references/REFERENCE.md +13 -0
- package/rules/java/spring-data-jpa/SKILL.md +241 -0
- package/rules/java/spring-data-jpa/references/REFERENCE.md +16 -0
- package/rules/java/spring-security/SKILL.md +161 -0
- package/rules/java/spring-security/references/REFERENCE.md +16 -0
- package/rules/java/spring-security/references/jwt-auth-flow.md +213 -0
- package/rules/java/testing-junit-mockito/SKILL.md +135 -0
- package/rules/java/testing-junit-mockito/references/REFERENCE.md +15 -0
- package/rules/java/testing-junit-mockito/references/junit5-patterns.md +159 -0
- package/rules/java/testing-junit-mockito/references/mockito-patterns.md +148 -0
- package/rules/java/testing-junit-mockito/references/spring-boot-testing.md +152 -0
- package/rules/javascript/best-practices/SKILL.md +64 -0
- package/rules/javascript/best-practices/references/REFERENCE.md +91 -0
- package/rules/javascript/language/SKILL.md +71 -0
- package/rules/javascript/language/references/REFERENCE.md +106 -0
- package/rules/javascript/tooling/SKILL.md +60 -0
- package/rules/javascript/tooling/references/REFERENCE.md +107 -0
- package/rules/metadata.json +54 -0
- package/rules/nestjs/api-standards/SKILL.md +47 -0
- package/rules/nestjs/api-standards/references/pagination-wrapper.md +87 -0
- package/rules/nestjs/architecture/SKILL.md +68 -0
- package/rules/nestjs/architecture/references/dynamic-module.md +53 -0
- package/rules/nestjs/caching/SKILL.md +51 -0
- package/rules/nestjs/caching/references/REFERENCE.md +13 -0
- package/rules/nestjs/caching/references/cache-patterns.md +183 -0
- package/rules/nestjs/configuration/SKILL.md +41 -0
- package/rules/nestjs/configuration/references/REFERENCE.md +13 -0
- package/rules/nestjs/configuration/references/config-patterns.md +184 -0
- package/rules/nestjs/controllers-services/SKILL.md +63 -0
- package/rules/nestjs/controllers-services/references/REFERENCE.md +14 -0
- package/rules/nestjs/controllers-services/references/controller-patterns.md +119 -0
- package/rules/nestjs/controllers-services/references/service-patterns.md +129 -0
- package/rules/nestjs/database/SKILL.md +102 -0
- package/rules/nestjs/database/references/REFERENCE.md +14 -0
- package/rules/nestjs/database/references/typeorm-patterns.md +156 -0
- package/rules/nestjs/deployment/SKILL.md +36 -0
- package/rules/nestjs/deployment/references/REFERENCE.md +13 -0
- package/rules/nestjs/deployment/references/deployment-patterns.md +140 -0
- package/rules/nestjs/documentation/SKILL.md +64 -0
- package/rules/nestjs/documentation/references/REFERENCE.md +13 -0
- package/rules/nestjs/documentation/references/swagger-patterns.md +139 -0
- package/rules/nestjs/error-handling/SKILL.md +55 -0
- package/rules/nestjs/error-handling/references/REFERENCE.md +13 -0
- package/rules/nestjs/error-handling/references/exception-filters.md +152 -0
- package/rules/nestjs/file-uploads/SKILL.md +35 -0
- package/rules/nestjs/file-uploads/references/REFERENCE.md +13 -0
- package/rules/nestjs/file-uploads/references/upload-patterns.md +125 -0
- package/rules/nestjs/observability/SKILL.md +39 -0
- package/rules/nestjs/observability/references/REFERENCE.md +13 -0
- package/rules/nestjs/observability/references/logging-metrics.md +175 -0
- package/rules/nestjs/performance/SKILL.md +60 -0
- package/rules/nestjs/performance/references/REFERENCE.md +13 -0
- package/rules/nestjs/performance/references/performance-patterns.md +107 -0
- package/rules/nestjs/real-time/SKILL.md +45 -0
- package/rules/nestjs/real-time/references/REFERENCE.md +13 -0
- package/rules/nestjs/real-time/references/websocket-patterns.md +121 -0
- package/rules/nestjs/scheduling/SKILL.md +39 -0
- package/rules/nestjs/scheduling/references/REFERENCE.md +13 -0
- package/rules/nestjs/scheduling/references/scheduling-patterns.md +137 -0
- package/rules/nestjs/search/SKILL.md +41 -0
- package/rules/nestjs/search/references/REFERENCE.md +13 -0
- package/rules/nestjs/search/references/search-patterns.md +137 -0
- package/rules/nestjs/security/SKILL.md +87 -0
- package/rules/nestjs/security/references/REFERENCE.md +14 -0
- package/rules/nestjs/security/references/authentication.md +151 -0
- package/rules/nestjs/testing/SKILL.md +40 -0
- package/rules/nestjs/testing/references/REFERENCE.md +14 -0
- package/rules/nestjs/testing/references/unit-testing.md +179 -0
- package/rules/nestjs/transport/SKILL.md +45 -0
- package/rules/nestjs/transport/references/REFERENCE.md +13 -0
- package/rules/nestjs/transport/references/microservices-patterns.md +170 -0
- package/rules/nextjs/app-router/SKILL.md +46 -0
- package/rules/nextjs/app-router/references/REFERENCE.md +14 -0
- package/rules/nextjs/app-router/references/routing-patterns.md +182 -0
- package/rules/nextjs/architecture/SKILL.md +44 -0
- package/rules/nextjs/architecture/references/fsd-structure.md +77 -0
- package/rules/nextjs/authentication/SKILL.md +29 -0
- package/rules/nextjs/authentication/references/auth-implementation.md +73 -0
- package/rules/nextjs/caching/SKILL.md +66 -0
- package/rules/nextjs/caching/references/REFERENCE.md +13 -0
- package/rules/nextjs/caching/references/cache-strategies.md +168 -0
- package/rules/nextjs/data-access-layer/SKILL.md +33 -0
- package/rules/nextjs/data-access-layer/references/patterns.md +66 -0
- package/rules/nextjs/data-fetching/SKILL.md +59 -0
- package/rules/nextjs/data-fetching/references/REFERENCE.md +13 -0
- package/rules/nextjs/data-fetching/references/fetch-patterns.md +160 -0
- package/rules/nextjs/internationalization/SKILL.md +105 -0
- package/rules/nextjs/internationalization/references/REFERENCE.md +13 -0
- package/rules/nextjs/internationalization/references/i18n-patterns.md +180 -0
- package/rules/nextjs/optimization/SKILL.md +64 -0
- package/rules/nextjs/optimization/references/REFERENCE.md +13 -0
- package/rules/nextjs/optimization/references/optimization-patterns.md +190 -0
- package/rules/nextjs/rendering/SKILL.md +91 -0
- package/rules/nextjs/rendering/references/REFERENCE.md +13 -0
- package/rules/nextjs/rendering/references/rendering-modes.md +163 -0
- package/rules/nextjs/server-actions/SKILL.md +46 -0
- package/rules/nextjs/server-actions/references/REFERENCE.md +13 -0
- package/rules/nextjs/server-actions/references/action-patterns.md +188 -0
- package/rules/nextjs/server-components/SKILL.md +52 -0
- package/rules/nextjs/server-components/references/REFERENCE.md +13 -0
- package/rules/nextjs/server-components/references/component-patterns.md +175 -0
- package/rules/nextjs/state-management/SKILL.md +73 -0
- package/rules/nextjs/state-management/references/REFERENCE.md +13 -0
- package/rules/nextjs/state-management/references/state-patterns.md +218 -0
- package/rules/nextjs/styling/SKILL.md +31 -0
- package/rules/nextjs/styling/references/implementation.md +56 -0
- package/rules/react/component-patterns/SKILL.md +66 -0
- package/rules/react/component-patterns/references/REFERENCE.md +126 -0
- package/rules/react/hooks/SKILL.md +60 -0
- package/rules/react/hooks/references/REFERENCE.md +132 -0
- package/rules/react/hooks.rule.md +79 -0
- package/rules/react/performance/SKILL.md +69 -0
- package/rules/react/performance/references/REFERENCE.md +143 -0
- package/rules/react/security/SKILL.md +46 -0
- package/rules/react/security/references/REFERENCE.md +170 -0
- package/rules/react/state-management/SKILL.md +56 -0
- package/rules/react/state-management/references/REFERENCE.md +137 -0
- package/rules/react/testing/SKILL.md +45 -0
- package/rules/react/testing/references/REFERENCE.md +149 -0
- package/rules/react/tooling/SKILL.md +39 -0
- package/rules/react/typescript/SKILL.md +53 -0
- package/rules/rust/actix-web/SKILL.md +160 -0
- package/rules/rust/actix-web/references/REFERENCE.md +13 -0
- package/rules/rust/actix-web/references/handler-patterns.md +198 -0
- package/rules/rust/async-graphql/SKILL.md +228 -0
- package/rules/rust/async-graphql/references/REFERENCE.md +13 -0
- package/rules/rust/async-graphql/references/schema-patterns.md +215 -0
- package/rules/rust/axum/SKILL.md +161 -0
- package/rules/rust/axum/references/REFERENCE.md +14 -0
- package/rules/rust/axum/references/handler-patterns.md +97 -0
- package/rules/rust/bevy/SKILL.md +206 -0
- package/rules/rust/bevy/references/REFERENCE.md +13 -0
- package/rules/rust/bevy/references/ecs-patterns.md +226 -0
- package/rules/rust/clap/SKILL.md +217 -0
- package/rules/rust/clap/references/REFERENCE.md +13 -0
- package/rules/rust/clap/references/derive-patterns.md +205 -0
- package/rules/rust/core/SKILL.md +154 -0
- package/rules/rust/core/references/REFERENCE.md +14 -0
- package/rules/rust/core/references/error-handling.md +92 -0
- package/rules/rust/diesel-orm/SKILL.md +176 -0
- package/rules/rust/diesel-orm/references/REFERENCE.md +13 -0
- package/rules/rust/diesel-orm/references/schema-patterns.md +206 -0
- package/rules/rust/rocket/SKILL.md +182 -0
- package/rules/rust/rocket/references/REFERENCE.md +13 -0
- package/rules/rust/rocket/references/handler-patterns.md +209 -0
- package/rules/rust/sea-orm/SKILL.md +230 -0
- package/rules/rust/sea-orm/references/REFERENCE.md +13 -0
- package/rules/rust/sea-orm/references/entity-patterns.md +221 -0
- package/rules/rust/serde-serialization/SKILL.md +150 -0
- package/rules/rust/serde-serialization/references/REFERENCE.md +13 -0
- package/rules/rust/serde-serialization/references/serialization-patterns.md +199 -0
- package/rules/rust/sqlx-database/SKILL.md +140 -0
- package/rules/rust/sqlx-database/references/REFERENCE.md +13 -0
- package/rules/rust/sqlx-database/references/query-patterns.md +210 -0
- package/rules/rust/tauri/SKILL.md +180 -0
- package/rules/rust/tauri/references/REFERENCE.md +13 -0
- package/rules/rust/tauri/references/command-patterns.md +209 -0
- package/rules/rust/tokio-runtime/SKILL.md +167 -0
- package/rules/rust/tokio-runtime/references/REFERENCE.md +14 -0
- package/rules/rust/tokio-runtime/references/async-patterns.md +137 -0
- package/rules/rust/tokio-runtime/references/synchronization.md +152 -0
- package/rules/rust/tonic/SKILL.md +231 -0
- package/rules/rust/tonic/references/REFERENCE.md +13 -0
- package/rules/rust/tonic/references/service-patterns.md +213 -0
- package/rules/rust/tracing/SKILL.md +214 -0
- package/rules/rust/tracing/references/REFERENCE.md +13 -0
- package/rules/rust/tracing/references/instrumentation.md +187 -0
- package/rules/typescript/best-practices/SKILL.md +108 -0
- package/rules/typescript/best-practices/references/REFERENCE.md +68 -0
- package/rules/typescript/language/SKILL.md +72 -0
- package/rules/typescript/language/references/REFERENCE.md +67 -0
- package/rules/typescript/patterns.rule.md +85 -0
- package/rules/typescript/security/SKILL.md +59 -0
- package/rules/typescript/security/references/REFERENCE.md +113 -0
- package/rules/typescript/tooling/SKILL.md +52 -0
- package/rules/typescript/tooling/references/REFERENCE.md +110 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Testing with JUnit & Mockito
|
|
3
|
+
description: JUnit 5, Mockito, Spring test slices, integration testing, and test organization.
|
|
4
|
+
metadata:
|
|
5
|
+
labels: [java, testing, junit, mockito]
|
|
6
|
+
triggers:
|
|
7
|
+
files: ['**/*Test.java', '**/*IT.java', '**/*Tests.java']
|
|
8
|
+
keywords: [JUnit, Jupiter, Mockito, '@Test', '@ExtendWith', '@MockBean', '@SpringBootTest', '@DataJpaTest', '@WebMvcTest']
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Testing Standards
|
|
12
|
+
|
|
13
|
+
## JUnit 5 Basics
|
|
14
|
+
|
|
15
|
+
```java
|
|
16
|
+
class UserServiceTest {
|
|
17
|
+
|
|
18
|
+
@Test
|
|
19
|
+
@DisplayName("should create user with valid data")
|
|
20
|
+
void shouldCreateUser() {
|
|
21
|
+
// Given
|
|
22
|
+
var request = new CreateUserRequest("John", "john@example.com");
|
|
23
|
+
|
|
24
|
+
// When
|
|
25
|
+
var user = userService.create(request);
|
|
26
|
+
|
|
27
|
+
// Then
|
|
28
|
+
assertThat(user.getName()).isEqualTo("John");
|
|
29
|
+
assertThat(user.getEmail()).isEqualTo("john@example.com");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@ParameterizedTest
|
|
33
|
+
@ValueSource(strings = {"", " ", "invalid"})
|
|
34
|
+
void shouldRejectInvalidEmail(String email) {
|
|
35
|
+
var request = new CreateUserRequest("John", email);
|
|
36
|
+
|
|
37
|
+
assertThatThrownBy(() -> userService.create(request))
|
|
38
|
+
.isInstanceOf(ValidationException.class);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@BeforeEach
|
|
42
|
+
void setUp() {
|
|
43
|
+
// Setup before each test
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@AfterEach
|
|
47
|
+
void tearDown() {
|
|
48
|
+
// Cleanup after each test
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Mockito
|
|
54
|
+
|
|
55
|
+
```java
|
|
56
|
+
@ExtendWith(MockitoExtension.class)
|
|
57
|
+
class OrderServiceTest {
|
|
58
|
+
|
|
59
|
+
@Mock
|
|
60
|
+
OrderRepository orderRepository;
|
|
61
|
+
|
|
62
|
+
@Mock
|
|
63
|
+
InventoryService inventoryService;
|
|
64
|
+
|
|
65
|
+
@InjectMocks
|
|
66
|
+
OrderService orderService;
|
|
67
|
+
|
|
68
|
+
@Test
|
|
69
|
+
void shouldCreateOrder() {
|
|
70
|
+
// Given
|
|
71
|
+
var request = new CreateOrderRequest("product-1", 2);
|
|
72
|
+
when(inventoryService.checkStock("product-1")).thenReturn(true);
|
|
73
|
+
when(orderRepository.save(any())).thenAnswer(inv -> inv.getArgument(0));
|
|
74
|
+
|
|
75
|
+
// When
|
|
76
|
+
var order = orderService.create(request);
|
|
77
|
+
|
|
78
|
+
// Then
|
|
79
|
+
assertThat(order).isNotNull();
|
|
80
|
+
verify(inventoryService).checkStock("product-1");
|
|
81
|
+
verify(orderRepository).save(any(Order.class));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Spring Test Slices
|
|
87
|
+
|
|
88
|
+
```java
|
|
89
|
+
// Full context
|
|
90
|
+
@SpringBootTest
|
|
91
|
+
class ApplicationTests {}
|
|
92
|
+
|
|
93
|
+
// Web layer only
|
|
94
|
+
@WebMvcTest(UserController.class)
|
|
95
|
+
class UserControllerTest {
|
|
96
|
+
@Autowired MockMvc mockMvc;
|
|
97
|
+
@MockBean UserService userService;
|
|
98
|
+
|
|
99
|
+
@Test
|
|
100
|
+
void shouldReturnUser() throws Exception {
|
|
101
|
+
when(userService.findById(1L)).thenReturn(Optional.of(new User(1L, "John")));
|
|
102
|
+
|
|
103
|
+
mockMvc.perform(get("/api/users/1"))
|
|
104
|
+
.andExpect(status().isOk())
|
|
105
|
+
.andExpect(jsonPath("$.name").value("John"));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// JPA layer only
|
|
110
|
+
@DataJpaTest
|
|
111
|
+
class UserRepositoryTest {
|
|
112
|
+
@Autowired UserRepository repository;
|
|
113
|
+
@Autowired TestEntityManager entityManager;
|
|
114
|
+
|
|
115
|
+
@Test
|
|
116
|
+
void shouldFindByEmail() {
|
|
117
|
+
entityManager.persist(new User("john@example.com"));
|
|
118
|
+
var user = repository.findByEmail("john@example.com");
|
|
119
|
+
assertThat(user).isPresent();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Best Practices
|
|
125
|
+
|
|
126
|
+
1. **Given-When-Then** structure for readability
|
|
127
|
+
2. **One assertion concept per test**
|
|
128
|
+
3. **Use test slices** to minimize context
|
|
129
|
+
4. **AssertJ** for fluent assertions
|
|
130
|
+
5. **Parameterized tests** for multiple inputs
|
|
131
|
+
|
|
132
|
+
## References
|
|
133
|
+
|
|
134
|
+
- [Test Slices](references/test-slices.md) - Available slices, customization
|
|
135
|
+
- [Mockito Patterns](references/mockito-patterns.md) - Stubbing, verification, argument captors
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# JUnit and Mockito Testing References
|
|
2
|
+
|
|
3
|
+
## References
|
|
4
|
+
|
|
5
|
+
- [**JUnit 5 Patterns**](junit5-patterns.md) - Test structure, parameterized tests, assertions
|
|
6
|
+
- [**Mockito Patterns**](mockito-patterns.md) - Mocking, stubbing, verification, spying
|
|
7
|
+
- [**Spring Boot Testing**](spring-boot-testing.md) - Slice tests, integration, Testcontainers
|
|
8
|
+
|
|
9
|
+
## Quick Checks
|
|
10
|
+
|
|
11
|
+
- [ ] Use @ExtendWith(MockitoExtension.class)
|
|
12
|
+
- [ ] @DisplayName for readable test names
|
|
13
|
+
- [ ] Parameterized tests for multiple inputs
|
|
14
|
+
- [ ] Slice tests (@WebMvcTest, @DataJpaTest) for focused testing
|
|
15
|
+
- [ ] Testcontainers for real database tests
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# JUnit 5 Testing Patterns
|
|
2
|
+
|
|
3
|
+
## Basic Test Structure
|
|
4
|
+
|
|
5
|
+
```java
|
|
6
|
+
import org.junit.jupiter.api.*;
|
|
7
|
+
import static org.junit.jupiter.api.Assertions.*;
|
|
8
|
+
|
|
9
|
+
class UserServiceTest {
|
|
10
|
+
|
|
11
|
+
private UserService userService;
|
|
12
|
+
|
|
13
|
+
@BeforeEach
|
|
14
|
+
void setUp() {
|
|
15
|
+
userService = new UserService();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@Test
|
|
19
|
+
@DisplayName("Should find user by ID")
|
|
20
|
+
void shouldFindUserById() {
|
|
21
|
+
User user = userService.findById(1L);
|
|
22
|
+
|
|
23
|
+
assertNotNull(user);
|
|
24
|
+
assertEquals("John", user.getName());
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@Test
|
|
28
|
+
void shouldThrowWhenUserNotFound() {
|
|
29
|
+
assertThrows(UserNotFoundException.class, () -> {
|
|
30
|
+
userService.findById(999L);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@AfterEach
|
|
35
|
+
void tearDown() {
|
|
36
|
+
// cleanup
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Parameterized Tests
|
|
42
|
+
|
|
43
|
+
```java
|
|
44
|
+
import org.junit.jupiter.params.ParameterizedTest;
|
|
45
|
+
import org.junit.jupiter.params.provider.*;
|
|
46
|
+
|
|
47
|
+
class ValidationTest {
|
|
48
|
+
|
|
49
|
+
@ParameterizedTest
|
|
50
|
+
@ValueSource(strings = {"a@b.com", "test@example.org"})
|
|
51
|
+
void shouldAcceptValidEmails(String email) {
|
|
52
|
+
assertTrue(EmailValidator.isValid(email));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@ParameterizedTest
|
|
56
|
+
@NullAndEmptySource
|
|
57
|
+
@ValueSource(strings = {"invalid", "@no-local.com"})
|
|
58
|
+
void shouldRejectInvalidEmails(String email) {
|
|
59
|
+
assertFalse(EmailValidator.isValid(email));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@ParameterizedTest
|
|
63
|
+
@CsvSource({
|
|
64
|
+
"1, 1, 2",
|
|
65
|
+
"2, 3, 5",
|
|
66
|
+
"10, 20, 30"
|
|
67
|
+
})
|
|
68
|
+
void shouldAddNumbers(int a, int b, int expected) {
|
|
69
|
+
assertEquals(expected, Calculator.add(a, b));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@ParameterizedTest
|
|
73
|
+
@MethodSource("userProvider")
|
|
74
|
+
void shouldValidateUser(User user, boolean expected) {
|
|
75
|
+
assertEquals(expected, UserValidator.isValid(user));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
static Stream<Arguments> userProvider() {
|
|
79
|
+
return Stream.of(
|
|
80
|
+
Arguments.of(new User("John", 25), true),
|
|
81
|
+
Arguments.of(new User("", 25), false),
|
|
82
|
+
Arguments.of(new User("John", -1), false)
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Nested Tests
|
|
89
|
+
|
|
90
|
+
```java
|
|
91
|
+
@DisplayName("OrderService")
|
|
92
|
+
class OrderServiceTest {
|
|
93
|
+
|
|
94
|
+
@Nested
|
|
95
|
+
@DisplayName("when creating order")
|
|
96
|
+
class WhenCreatingOrder {
|
|
97
|
+
|
|
98
|
+
@Test
|
|
99
|
+
void shouldCreateWithValidItems() { }
|
|
100
|
+
|
|
101
|
+
@Test
|
|
102
|
+
void shouldRejectEmptyCart() { }
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
@Nested
|
|
106
|
+
@DisplayName("when canceling order")
|
|
107
|
+
class WhenCancelingOrder {
|
|
108
|
+
|
|
109
|
+
@Test
|
|
110
|
+
void shouldCancelPendingOrder() { }
|
|
111
|
+
|
|
112
|
+
@Test
|
|
113
|
+
void shouldNotCancelShippedOrder() { }
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Assertions
|
|
119
|
+
|
|
120
|
+
```java
|
|
121
|
+
// Multiple assertions
|
|
122
|
+
assertAll("user",
|
|
123
|
+
() -> assertEquals("John", user.getName()),
|
|
124
|
+
() -> assertEquals(25, user.getAge()),
|
|
125
|
+
() -> assertTrue(user.isActive())
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
// Timeout
|
|
129
|
+
assertTimeout(Duration.ofSeconds(2), () -> {
|
|
130
|
+
longRunningOperation();
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// Exception details
|
|
134
|
+
var exception = assertThrows(ValidationException.class, () -> {
|
|
135
|
+
service.validate(invalidData);
|
|
136
|
+
});
|
|
137
|
+
assertEquals("Invalid input", exception.getMessage());
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Test Lifecycle
|
|
141
|
+
|
|
142
|
+
```java
|
|
143
|
+
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
|
144
|
+
class ExpensiveResourceTest {
|
|
145
|
+
|
|
146
|
+
private Database db;
|
|
147
|
+
|
|
148
|
+
@BeforeAll
|
|
149
|
+
void initDatabase() {
|
|
150
|
+
db = new Database();
|
|
151
|
+
db.connect();
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
@AfterAll
|
|
155
|
+
void closeDatabase() {
|
|
156
|
+
db.disconnect();
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
```
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# Mockito Testing Patterns
|
|
2
|
+
|
|
3
|
+
## Basic Mocking
|
|
4
|
+
|
|
5
|
+
```java
|
|
6
|
+
import org.junit.jupiter.api.Test;
|
|
7
|
+
import org.junit.jupiter.api.extension.ExtendWith;
|
|
8
|
+
import org.mockito.InjectMocks;
|
|
9
|
+
import org.mockito.Mock;
|
|
10
|
+
import org.mockito.junit.jupiter.MockitoExtension;
|
|
11
|
+
import static org.mockito.Mockito.*;
|
|
12
|
+
|
|
13
|
+
@ExtendWith(MockitoExtension.class)
|
|
14
|
+
class OrderServiceTest {
|
|
15
|
+
|
|
16
|
+
@Mock
|
|
17
|
+
private UserRepository userRepository;
|
|
18
|
+
|
|
19
|
+
@Mock
|
|
20
|
+
private OrderRepository orderRepository;
|
|
21
|
+
|
|
22
|
+
@InjectMocks
|
|
23
|
+
private OrderService orderService;
|
|
24
|
+
|
|
25
|
+
@Test
|
|
26
|
+
void shouldCreateOrder() {
|
|
27
|
+
// Given
|
|
28
|
+
User user = new User(1L, "John");
|
|
29
|
+
when(userRepository.findById(1L)).thenReturn(Optional.of(user));
|
|
30
|
+
when(orderRepository.save(any(Order.class))).thenAnswer(inv -> {
|
|
31
|
+
Order order = inv.getArgument(0);
|
|
32
|
+
order.setId(100L);
|
|
33
|
+
return order;
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// When
|
|
37
|
+
Order order = orderService.createOrder(1L, List.of(item1, item2));
|
|
38
|
+
|
|
39
|
+
// Then
|
|
40
|
+
assertNotNull(order);
|
|
41
|
+
assertEquals(100L, order.getId());
|
|
42
|
+
verify(orderRepository).save(any(Order.class));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Stubbing
|
|
48
|
+
|
|
49
|
+
```java
|
|
50
|
+
// Return value
|
|
51
|
+
when(mock.method()).thenReturn(value);
|
|
52
|
+
|
|
53
|
+
// Throw exception
|
|
54
|
+
when(mock.method()).thenThrow(new RuntimeException());
|
|
55
|
+
|
|
56
|
+
// Multiple calls
|
|
57
|
+
when(mock.method())
|
|
58
|
+
.thenReturn(first)
|
|
59
|
+
.thenReturn(second)
|
|
60
|
+
.thenThrow(new RuntimeException());
|
|
61
|
+
|
|
62
|
+
// Argument matchers
|
|
63
|
+
when(userRepo.findByEmail(anyString())).thenReturn(user);
|
|
64
|
+
when(userRepo.findByAge(argThat(age -> age > 18))).thenReturn(adults);
|
|
65
|
+
|
|
66
|
+
// Void methods
|
|
67
|
+
doNothing().when(mock).voidMethod();
|
|
68
|
+
doThrow(new RuntimeException()).when(mock).voidMethod();
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Verification
|
|
72
|
+
|
|
73
|
+
```java
|
|
74
|
+
// Called once (default)
|
|
75
|
+
verify(mock).method();
|
|
76
|
+
|
|
77
|
+
// Called specific times
|
|
78
|
+
verify(mock, times(3)).method();
|
|
79
|
+
verify(mock, never()).method();
|
|
80
|
+
verify(mock, atLeast(2)).method();
|
|
81
|
+
verify(mock, atMost(5)).method();
|
|
82
|
+
|
|
83
|
+
// With argument capture
|
|
84
|
+
ArgumentCaptor<Order> captor = ArgumentCaptor.forClass(Order.class);
|
|
85
|
+
verify(orderRepo).save(captor.capture());
|
|
86
|
+
Order saved = captor.getValue();
|
|
87
|
+
assertEquals(expectedTotal, saved.getTotal());
|
|
88
|
+
|
|
89
|
+
// Verification order
|
|
90
|
+
InOrder inOrder = inOrder(first, second);
|
|
91
|
+
inOrder.verify(first).method();
|
|
92
|
+
inOrder.verify(second).method();
|
|
93
|
+
|
|
94
|
+
// No more interactions
|
|
95
|
+
verifyNoMoreInteractions(mock);
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Spying
|
|
99
|
+
|
|
100
|
+
```java
|
|
101
|
+
// Partial mock - real object with stubbed methods
|
|
102
|
+
@Spy
|
|
103
|
+
private List<String> spiedList = new ArrayList<>();
|
|
104
|
+
|
|
105
|
+
@Test
|
|
106
|
+
void shouldSpyRealObject() {
|
|
107
|
+
spiedList.add("one");
|
|
108
|
+
spiedList.add("two");
|
|
109
|
+
|
|
110
|
+
verify(spiedList).add("one");
|
|
111
|
+
assertEquals(2, spiedList.size()); // Real behavior
|
|
112
|
+
|
|
113
|
+
// Override specific method
|
|
114
|
+
doReturn(100).when(spiedList).size();
|
|
115
|
+
assertEquals(100, spiedList.size());
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## BDD Style
|
|
120
|
+
|
|
121
|
+
```java
|
|
122
|
+
import static org.mockito.BDDMockito.*;
|
|
123
|
+
|
|
124
|
+
@Test
|
|
125
|
+
void shouldProcessPayment() {
|
|
126
|
+
// Given
|
|
127
|
+
given(paymentGateway.process(any())).willReturn(PaymentResult.SUCCESS);
|
|
128
|
+
|
|
129
|
+
// When
|
|
130
|
+
boolean result = paymentService.pay(order);
|
|
131
|
+
|
|
132
|
+
// Then
|
|
133
|
+
then(paymentGateway).should().process(any());
|
|
134
|
+
assertThat(result).isTrue();
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Static Mocking
|
|
139
|
+
|
|
140
|
+
```java
|
|
141
|
+
try (MockedStatic<Utils> utilities = mockStatic(Utils.class)) {
|
|
142
|
+
utilities.when(() -> Utils.generateId()).thenReturn("mocked-id");
|
|
143
|
+
|
|
144
|
+
String id = Utils.generateId();
|
|
145
|
+
|
|
146
|
+
assertEquals("mocked-id", id);
|
|
147
|
+
}
|
|
148
|
+
```
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Spring Boot Testing
|
|
2
|
+
|
|
3
|
+
## Slice Tests
|
|
4
|
+
|
|
5
|
+
```java
|
|
6
|
+
// Web layer only
|
|
7
|
+
@WebMvcTest(UserController.class)
|
|
8
|
+
class UserControllerTest {
|
|
9
|
+
|
|
10
|
+
@Autowired
|
|
11
|
+
private MockMvc mockMvc;
|
|
12
|
+
|
|
13
|
+
@MockitoBean
|
|
14
|
+
private UserService userService;
|
|
15
|
+
|
|
16
|
+
@Test
|
|
17
|
+
void shouldGetUser() throws Exception {
|
|
18
|
+
when(userService.findById(1L)).thenReturn(new User(1L, "John"));
|
|
19
|
+
|
|
20
|
+
mockMvc.perform(get("/users/1"))
|
|
21
|
+
.andExpect(status().isOk())
|
|
22
|
+
.andExpect(jsonPath("$.name").value("John"));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@Test
|
|
26
|
+
void shouldCreateUser() throws Exception {
|
|
27
|
+
mockMvc.perform(post("/users")
|
|
28
|
+
.contentType(MediaType.APPLICATION_JSON)
|
|
29
|
+
.content("""
|
|
30
|
+
{"name": "John", "email": "john@example.com"}
|
|
31
|
+
"""))
|
|
32
|
+
.andExpect(status().isCreated());
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// JPA layer only
|
|
37
|
+
@DataJpaTest
|
|
38
|
+
class UserRepositoryTest {
|
|
39
|
+
|
|
40
|
+
@Autowired
|
|
41
|
+
private TestEntityManager entityManager;
|
|
42
|
+
|
|
43
|
+
@Autowired
|
|
44
|
+
private UserRepository userRepository;
|
|
45
|
+
|
|
46
|
+
@Test
|
|
47
|
+
void shouldFindByEmail() {
|
|
48
|
+
entityManager.persist(new User("John", "john@example.com"));
|
|
49
|
+
|
|
50
|
+
Optional<User> found = userRepository.findByEmail("john@example.com");
|
|
51
|
+
|
|
52
|
+
assertThat(found).isPresent();
|
|
53
|
+
assertThat(found.get().getName()).isEqualTo("John");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Integration Tests
|
|
59
|
+
|
|
60
|
+
```java
|
|
61
|
+
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
|
62
|
+
class OrderIntegrationTest {
|
|
63
|
+
|
|
64
|
+
@Autowired
|
|
65
|
+
private TestRestTemplate restTemplate;
|
|
66
|
+
|
|
67
|
+
@Test
|
|
68
|
+
void shouldCreateAndRetrieveOrder() {
|
|
69
|
+
// Create
|
|
70
|
+
OrderRequest request = new OrderRequest(List.of(item1, item2));
|
|
71
|
+
ResponseEntity<Order> createResponse = restTemplate
|
|
72
|
+
.postForEntity("/orders", request, Order.class);
|
|
73
|
+
|
|
74
|
+
assertThat(createResponse.getStatusCode()).isEqualTo(HttpStatus.CREATED);
|
|
75
|
+
Long orderId = createResponse.getBody().getId();
|
|
76
|
+
|
|
77
|
+
// Retrieve
|
|
78
|
+
ResponseEntity<Order> getResponse = restTemplate
|
|
79
|
+
.getForEntity("/orders/" + orderId, Order.class);
|
|
80
|
+
|
|
81
|
+
assertThat(getResponse.getBody().getItems()).hasSize(2);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Testcontainers
|
|
87
|
+
|
|
88
|
+
```java
|
|
89
|
+
@SpringBootTest
|
|
90
|
+
@Testcontainers
|
|
91
|
+
class PostgresIntegrationTest {
|
|
92
|
+
|
|
93
|
+
@Container
|
|
94
|
+
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15")
|
|
95
|
+
.withDatabaseName("testdb")
|
|
96
|
+
.withUsername("test")
|
|
97
|
+
.withPassword("test");
|
|
98
|
+
|
|
99
|
+
@DynamicPropertySource
|
|
100
|
+
static void configureProperties(DynamicPropertyRegistry registry) {
|
|
101
|
+
registry.add("spring.datasource.url", postgres::getJdbcUrl);
|
|
102
|
+
registry.add("spring.datasource.username", postgres::getUsername);
|
|
103
|
+
registry.add("spring.datasource.password", postgres::getPassword);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
@Autowired
|
|
107
|
+
private UserRepository userRepository;
|
|
108
|
+
|
|
109
|
+
@Test
|
|
110
|
+
void shouldPersistUser() {
|
|
111
|
+
User saved = userRepository.save(new User("John", "john@example.com"));
|
|
112
|
+
|
|
113
|
+
assertThat(saved.getId()).isNotNull();
|
|
114
|
+
assertThat(userRepository.findById(saved.getId())).isPresent();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Test Configuration
|
|
120
|
+
|
|
121
|
+
```java
|
|
122
|
+
@TestConfiguration
|
|
123
|
+
class TestConfig {
|
|
124
|
+
|
|
125
|
+
@Bean
|
|
126
|
+
@Primary
|
|
127
|
+
public EmailService mockEmailService() {
|
|
128
|
+
return mock(EmailService.class);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
@SpringBootTest
|
|
133
|
+
@Import(TestConfig.class)
|
|
134
|
+
class ServiceTest {
|
|
135
|
+
// Uses mock EmailService
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Test Properties
|
|
140
|
+
|
|
141
|
+
```properties
|
|
142
|
+
# src/test/resources/application-test.properties
|
|
143
|
+
spring.datasource.url=jdbc:h2:mem:testdb
|
|
144
|
+
spring.jpa.hibernate.ddl-auto=create-drop
|
|
145
|
+
spring.jpa.show-sql=true
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
```java
|
|
149
|
+
@SpringBootTest
|
|
150
|
+
@ActiveProfiles("test")
|
|
151
|
+
class TestWithProfile { }
|
|
152
|
+
```
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: JavaScript Best Practices
|
|
3
|
+
description: Idiomatic JavaScript patterns and conventions for maintainable code.
|
|
4
|
+
metadata:
|
|
5
|
+
labels: [javascript, best-practices, conventions, code-quality]
|
|
6
|
+
triggers:
|
|
7
|
+
files: ['**/*.js', '**/*.mjs']
|
|
8
|
+
keywords: [module, import, export, error, validation]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# JavaScript Best Practices
|
|
12
|
+
|
|
13
|
+
## **Priority: P1 (OPERATIONAL)**
|
|
14
|
+
|
|
15
|
+
Conventions and patterns for writing maintainable JavaScript.
|
|
16
|
+
|
|
17
|
+
## Implementation Guidelines
|
|
18
|
+
|
|
19
|
+
- **Naming**: `camelCase` (vars/funcs), `PascalCase` (classes), `UPPER_SNAKE` (constants).
|
|
20
|
+
- **Errors**: Throw `Error` objects only. Handle all async errors.
|
|
21
|
+
- **Comments**: JSDoc for APIs. Explain "why" not "what".
|
|
22
|
+
- **Files**: One entity per file. `index.js` for exports.
|
|
23
|
+
- **Modules**: Named exports only. Order: Ext -> Int -> Rel.
|
|
24
|
+
|
|
25
|
+
## Anti-Patterns
|
|
26
|
+
|
|
27
|
+
- **No Globals**: Encapsulate state.
|
|
28
|
+
- **No Magic Numbers**: Use `const`.
|
|
29
|
+
- **No Nesting**: Guard clauses/early returns.
|
|
30
|
+
- **No Defaults**: Use named exports.
|
|
31
|
+
- **No Side Effects**: Keep functions pure.
|
|
32
|
+
|
|
33
|
+
## Code
|
|
34
|
+
|
|
35
|
+
```javascript
|
|
36
|
+
// Constants
|
|
37
|
+
const STATUS = { OK: 200, ERROR: 500 };
|
|
38
|
+
|
|
39
|
+
// Errors
|
|
40
|
+
class APIError extends Error {
|
|
41
|
+
constructor(msg, code) {
|
|
42
|
+
super(msg);
|
|
43
|
+
this.code = code;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Async + JDoc
|
|
48
|
+
/** @throws {APIError} */
|
|
49
|
+
export async function getData(id) {
|
|
50
|
+
if (!id) throw new APIError('Missing ID', 400);
|
|
51
|
+
const res = await fetch(`/api/${id}`);
|
|
52
|
+
if (!res.ok) throw new APIError('Failed', res.status);
|
|
53
|
+
return res.json();
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Reference & Examples
|
|
58
|
+
|
|
59
|
+
For module patterns and project structure:
|
|
60
|
+
See [references/REFERENCE.md](references/REFERENCE.md).
|
|
61
|
+
|
|
62
|
+
## Related Topics
|
|
63
|
+
|
|
64
|
+
language | tooling
|