Terraform Azure
- Terraform Azure AD provider
- Terraform — AzureAD & AzureRM
- Manage Microsoft Entra ID users and groups
- Azure RM provider
- How to Use Terraform on Microsoft Azure
- Build infrastructure on Azure
- How to use Azure Resource Groups
- Microsoft Azure resource groups Introduction and best practices
- Terraform for_each
Learnings
- Generic builder pattern in Java 8 – Tutorials (wordpress.com)
- Template Method Design Pattern in Java | DigitalOcean
- Define variables - Azure Pipelines | Microsoft Learn
Patterns
Toolbox with solutions to solving common design problems, like how to construct objects, structure your components, implement logis.. Software Design Patterns Tutorial - GeeksforGeeks
- Strategy pattern - We define multiple algorithms and let client applications pass the algorithm to be used as a parameter.
- Observer design pattern - Object that watches the state of another Object is called observer, and the Object that is being watched is called subject.
- Template method pattern - The template method defines the steps to execute an algorithm, and it can provide a default implementation that might be common for all or some of the subclasses.
- Chain of responsibility pattern - where a request from the client is passed to a chain of objects to process them. Then the object in the chain will decide who will be processing the request and whether the request is required to be sent to the next object in the chain or not.
Structural patterns
- Flyweight - Reduce memory footprint by keeping references of objects in hashmap, like java string constant pool
- proxy - placeholder that provides controlled access to an object, like additional layer of security or logging
- Façade - hides away the complexity of the underlying system, by providing a simplified view.
- Bridge - The bridge pattern allows the Abstraction and the Implementation to be developed independently, by encapsulating an implementation class (the bridge) inside of an interface class. is an application of the old advice, "prefer composition over inheritance"
- Adapter - This pattern involves a single class, known as the adapter, which is responsible for joining functionalities of independent or incompatible interfaces.
- Decorator - allows behavior to be added to individual objects, dynamically by putting a façade/wrapper on top of it.
- Composite - The client uses the component class interface to interact with objects in the composition structure.
Creational patterns
- Factory - encapsulating creation logic in separate static method, complex objects...
- Builder - construct a complex object step by step. allowing the same construction process to create different representations.
- Singleton - single object creation logging, driver objects, caching, and thread pool, database connections
- Prototype - save object creation by copying existing one, cloning, since object creation is heave process.
SOLID
- Single Responsibility Principle - The more responsibilities your class has, the more often you need to change it. You need to change your class as soon as one of its responsibilities changes.
- Open/Closed Principle - requires software components to be open for extension, but closed for modification. You can achieve that by introducing interfaces for which you can provide different implementations.
- Liskov Substitution Principle - objects of a superclass shall be replaceable with objects of its subclasses without breaking the application. Child classes may extend the behavior but never narrow down behavior.
- Interface Segregation Principle - Clients should not be forced to depend upon interfaces that they do not use.
- Dependency Inversion Principle - high-level and low-level modules should depend on abstractions. Does not change the direction of the dependency as the name is suggesting. It splits the dependency between the high-level and low-level modules by introducing an abstraction between them. So in the end, you get two dependencies.
Unit Tests Red, Green, Refactor
- Red — think about what you want to develop
- Green — think about how to make your tests pass
- Refactor — think about how to improve your existing implementation
The red phase is always the starting point of the red, green, refactor cycle. The purpose of this phase is to write a test that informs the implementation of a feature. Give that method a proper comprehensive Gherkin style name, that explains your intention, starting condition, functionality under test, and finally the outcome. The green phase is where you implement code to make your test pass. The goal is to find a solution, without worrying about optimizing your implementation. In the refactor phase, you are still “in the green.” You can begin thinking about how to implement your code better or more efficiently.
Unit tests that make sense
All about detecting bugs before slipping through to production
Unit tests are only valuable if you're are covering all preconditions (GIVEN) vs expected results (THEN...AND). I always try to formulating my test method names Gherkin style. This forces you to a way of thinking about what your functionality should be accomplishing under every thinkable scenario. I experienced too many units tests that are meaningless, sole reason for their existence is to satisfying test coverage numbers, pure nonsense sitting in the way.
Scenario: Scenario 1
Given preconditions
When actions
Then results
Alike ...
@Test public void givenDefaultMethod_whenCallRealMethod_thenNoExceptionIsRaised()
Like the baeldung always demonstrates
Unit Tests FIRST principle
Verifying that a known fixed input produces a known fixed output. But first step back. What is a unit in general? A unit is normally a method, constructor or deconstructor. Comprehensibility: structural characteristics of software that may indicate a code or design problem that makes software hard to evolve and maintain (compre-hensibility and maintainability).
How much should you unit test? Be careful not to spend too much effort trying to achieve 100% coverage – it may not even be possible or feasible, and really the quality of your tests is the important thing.
- FIRST-Principle (Fast, Independent, Repeatable, Self-Checking and Timely)
- How to write Gherkin tests (Gherkin steps....)
Consumer-Driven Contract
Consumer-driven contract (CDD) is an approach where the consumer drives the changes in the API of the producer. Consumer-driven contract testing is an approach to formalize above mentioned expectations into a contract between each consumer-provider pair. Once the contract is established between Provider and Consumer, this ensures that the contract will not break suddenly.
- https://spring.io/projects/spring-cloud-contract
- https://dzone.com/articles/consumer-driven-contract-testing-with-spring-cloud-contract
SpringBoot Controller testing (slices, load only a partial contexts)
There are different ways to test your Controller (Web or API Layer) classes in Spring Boot, some provide support to write pure Unit Tests and some others are more useful for Integration Tests.
- https://thepracticaldeveloper.com/guide-spring-boot-controller-tests/#mockmvc-and-webmvctest-code-example
- Samples from spring framework
Hamcrest and AssertJ
AssertJ provides a rich set of assertions, truly helpful error messages, improves test code readability and is designed to be super easy to use within your favorite IDE.
- AssertJ - fluent assertions java library
- JUnit 5 Tutorial: Writing Assertions With AssertJ
- Hamcrest Tutorial
- Hamcrest at Baeldung
Testing Kafka and Spring Boot
- https://www.baeldung.com/spring-boot-kafka-testing
- https://blog.mimacom.com/testing-apache-kafka-with-spring-boot-junit5/
- https://medium.com/trendyol-tech/how-to-integration-test-on-spring-kafka-producer-cb9d1caf0795
- https://www.confluent.io/blog/advanced-testing-techniques-for-spring-kafka/
- https://kreuzwerker.de/en/post/testing-a-kafka-consumer-with-avro-schema-messages-in-your-spring-boot
- https://medium.com/@igorvlahek1/no-need-for-schema-registry-in-your-spring-kafka-tests-a5b81468a0e1
Junit5 and TestContainers
- https://www.testcontainers.org/test_framework_integration/junit_5/
- https://karuppiah7890.github.io/blog/posts/testcontainers-part-1-an-introduction-to-a-new-way-of-integration-testing/
- https://www.testcontainers.org/quickstart/junit_5_quickstart/
- https://www.baeldung.com/spring-boot-testcontainers-integration-test
- https://fullstackcode.dev/2021/05/16/springboot-integration-testing-with-testcontainers/
- Junit 5 testcontainers and kafka
- https://dev.to/rieckpil/write-spring-boot-integration-tests-with-testcontainers-junit-4-5-40am
- SpringBoot @DataJpaTest is throwing Failed to load ApplicationContext exception
- How to populate data in testcontainers?
- Kafkacontainers test example
- https://github.com/jupiter-tools/spring-test-kafka
- Example from above
- Best TestContainer post with postgreSQL and Flyway
The rules are the same but there is a slight difference. @DataJpaTest is annotated with @AutoConfigureTestDatabase itself. This annotation replaces any data source with the H2 instance by default. So, we need to override this behavior by adding replace=Replace.NONE property.