Field injection hides dependencies inside private fields, making it difficult to replace or mock them during unit tests. Constructor injection is preferred because it makes dependencies explicit and easier to manage.
Spring uses reflection to inject dependencies directly into private fields annotated with @Autowired after the object is instantiated. This bypasses constructors and setters.
Without proper Spring test annotations like @SpringBootTest or @ExtendWith(SpringExtension.class), Spring does not create the application context and does not inject dependencies, causing NullPointerException.
Constructor injection uses a constructor annotated with @Autowired (optional in recent Spring versions) that takes dependencies as parameters and assigns them to final fields. This makes dependencies explicit and immutable.
When you create an object with new, Spring does not manage it and does not inject dependencies. The private field remains null, causing NullPointerException when accessed.