Craig Walls

author
+ Follow
since Sep 19, 2003
jroller.com
Cows and Likes
Cows
Total received
8
In last 30 days
0
Total given
0
Likes
Total received
42
Received in last 30 days
0
Total given
0
Given in last 30 days
0
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Craig Walls


Well, it *is* the weekend and I was busy with family yesterday, but...

There's no reason why you couldn't use Spring (@RunWith(SpringRunner.class)) in the service test and only a small reason why you couldn't use Mockito in the controller test.

First, you should be able to use @RunWith(SpringRunner.class) in the service test, but when you do that, Spring will become responsible for creating and injecting the beans that will be in the context of the test. That's fine, but it will generally do so by loading all of the beans it can find. You can narrow that down to only a slice of your application and then mock what those beans need (using @MockBean), but how you do that depends on the structure of your app. It'd be hard for me to tell you how to do that in a forum like this without knowing more about the structure of your app, but in short: The @SpringBootTest annotation has a "classes" attribute that lets you pick and choose certain configuration classes so that you can refine what you want in the test and what you don't.

You *could* use @RunWith(MockitoJUnitRunner.class) to test controllers, but then you won't get the benefit of a mocked out Spring MVC to test the controller as a controller (by sending requests to it). That is, the MockMvc that you use to test the controller actually sets up a minimal Spring application context *and* mocks out just enough Spring MVC web framework to be able to test the controller without actually setting up a server. The @MockBean in this test ensure that the mocked service ends up in that application context so that it can be injected into the controller. And...the @SpringBootTest/@RunWith(SpringRunner.class) combination ensures that the MockMvc object is created for you. (In truth, you can actually set all of that up manually and not annotate the class with @SpringBootTest/@RunWith(SpringRunner.class), but it's a lot more work. Prior to Spring Boot, that's how MockMvc was commonly used, but I'm super-happy that I don't have to do it that way anymore.)

Hope that helps. Now I'm going to resume my weekend.


must Janik wrote:Still waiting Can not find answer for that.

11 months ago

Let's start with BookFindOperationsServiceTest, as it's the non-Spring one. In this case, it is annotated with @RunWith(MockitoJUnitRunner.class), which puts Mockito in charge of setting the test up (not Spring) and thus the BookFindOperationsService, which is annotated with @InjectMocks will be injected by Mockito with the BookRepository mock object. Inside of the test method, you train the mock (the line with "when(bookRepository.findByAuthorAllignoreCase..."). But in no way is Spring involved in this particular test. Mockito handles the injection.

In BookFindOperationsControllerTest, I am assuming that it the class is annotated with @RunWith(SpringRunner.class), and possibly also annotated with @SpringBootTest or @ContextConfiguration to guide the SpringRunner in how to load the application context. In this case, Spring is put in charge of creating the application context, loading it with beans, and...in the case of the BookFindOperationsService instance, loading the mocked bean into the application context. You still train the mock inside of the test method, but rather than Mockito injecting it into the controller, it gets put into the Spring application context as a bean and is injected into the controller by Spring itself.

must Janik wrote:Could you tell me, why in service Spring Context is not involved and in controller it is? Where it comes from?

11 months ago
Again, another great example of using functions (lambdas or method references) in Spring. In fact, I cover this in the book, as well.

meenakshi sundar wrote:Another interesting read on the functional web framework...

functional-web-framework

11 months ago

Yes, this is a good example, I often use lambdas or method references in place of a RowMapper when working with JdbcTemplate (in fact, I cover this in the book). I wasn't thinking of that use of lambdas as being DI, though...although I guess you could say that they are. I was thinking more of how you'd inject a lambda in the context of a configuration class.


meenakshi sundar wrote:I have never personally used, but I have seen some examples around ...

Spring 4 on Java 8


11 months ago

meenakshi sundar wrote:[
Appreciate your answer, though you say it is up to the individual's personal preference,
you must be having some reason for your choice...



Sure, let me expand on that a bit:

1. I prefer Spring Boot auto-config over any other option because why should I write configuration if I don't have to? Every single line of code, whether it be business logic or configuration is a liability. If I can get the same benefit from writing no configuration and letting Spring Boot handle it for me that I can get from writing explicit configuration, then I will have less liability if I let Spring Boot do the work.
2. I prefer component-scanning and autowiring over the remaining options for a similar reason. If by simply putting an annotation on a class I can suddenly make Spring manage its lifecycle and dependency injection, then that's better than me explicitly writing configuration to do the same thing. Also, if I write any explicit configuration for components that I also have to write, I find that there's at least a tiny bit of duplication (at very least in the type name) and I must make sure that any refactoring I do on the component is also reflected in the configuration (IDEs usually are good at that, but all the same...).
3. I prefer JavaConfig over XML because I do get all of the benefits of Java--type-safety, IDE support for refactoring, testing, and I have the option of even writing some logic into my configuration--that I don't get with XML config. But generally I only resort to explicit JavaConfig if neither 1 or 2 are an option...or, in a more rare circumstance, I find myself writing Boot autoconfiguration for a library so that someone else can benefit from it.
4. I avoid XML configuration at almost any cost, primarily  because of the benefits afforded by the other 3 options. Although I never hated XML configuration when that was the norm, I must admit now that viewing XML configuration makes my eyes hurt. As I said before, though, I might still use @ImportResource to link in some existing XML configuration that I'm not ready or interested in rewriting into JavaConfig.
11 months ago

In the past (a long time ago), I tried using Groovy for configuring a Spring context. But it never stuck with me and haven't used it since. I do not cover it in the book.

That said, if you find value in it, then by all means, go for it! I just can't help you much with it if you do.

meenakshi sundar wrote:I personally use Groovy for writing some useful and fun scripts...

I have read somewhere that (also looked at few examples) Groovy DSL feature can be leveraged for Spring configurations and may season programmers use Groovy for
Spring configuration extensively, What is your personal preference and have you discussed using Groovy as a Configuration method
in your book?
 

11 months ago

When testing the service, Spring really isn't involved and you are responsible for injecting the mock into the service (in your case, you're letting Mockito do it with @InjectMocks). In short, there is no Spring container and you (or Mockito) is taking on the responsibility for the lifecycle and injection of the components.

When testing the controller, there *is* a Spring application context and so Spring is responsible for the lifecycle and injection of the components. The @MockBean isn't much different than @Mock from a mocking standpoint, but what makes it special in the case of a Spring test is that it ensure that the mock object is registered as a bean in the Spring application context so that Spring can find it and inject it. If you weren't using @MockBean in this test, Spring will try to do the injection, but not find a bean of that type and will fail.


must Janik wrote:Hey. Im coming to you with question.
I wanted to test same method from controller and service layer.
Here is it:





Here is the test for Controller:


And here is for service;


The question is... Why do I have to use @MockBean annotation in controller, why not @Mock for BookFindOperationsService bookService. Same question for service, why do I need to @Mock repository, why not to use @MockBean?

11 months ago
To some degree, it's a matter of individual taste. But I prefer...in this order...

1. Spring Boot autoconfiguration for any configuration that is essentially boilerplate.
2. Component-scanning/autowiring (e.g., @Component/@Controller/@Repository/@Service/etc and @Autowired) for the beans whose code is in my control.
3. JavaConfig (e.g., @Bean methods) for beans that aren't covered by #1 and #2
4. XML almost never...usually only when I'm (temporarily) leveraging some existing config that is already written in XML.

I never use @Inject, but if you like it, then it's a suitable alternative for @Autowired.


meenakshi sundar wrote:Craig,

  With many of options available via XML configuration, Component scanning, and auto wiring, @Inject annotation,
  what would be your advice and the best practice to choose the best DI mechanism suitable for a given situation in Spring?


Thanks
Sundar

11 months ago

I don't cover testing explicitly in the book, but I do have a few tests sprinkled around in the book and in the sample code that accompanies the book. In short, using Spring Boot you just annotate your test class with @SpringBootTest and @RunWith(SpringRunner.class) and then @Autowire any beans you want to test into the test class itself.

To get you started, if you create a new project using the Initializr (start.spring.io), you will get a *very* simple test that proves that the application context loads cleanly. Looks a little like this:



You would, of course, write more tests (using this as a template) to assert application/component behavior.

Julian Isaac wrote:What's the quickest and easiest way to create a Spring context to use in junit test classes?

Are there strategies for  this covered in the book?

Thanks! :-)

YoungJules

11 months ago

For what it's worth, I write a simple (non-server) controller test as early as chapter 1 in Spring in Action 5. And then, later in chapter 11, I show how to write a test that fires up a server. In that case, it is in the context of WebFlux, but the same thing would work even for testing Spring MVC.

Igor Janicki wrote:@Peter Rooke: Thanks.

Now I think how to perform tests with JUnit.

I would add some @tests using Apache HTTP client.
However how to start automatically the local server with @Controller ?

I use Eclipse and Maven.

11 months ago
This edition does cover microservices, although that isn't the main message of the book. In chapters 13-15, I cover service registry (Eureka), config server, and the circuit breaker pattern (Hystrix) as a taste of what I believe are some of the most elemental pieces of working with microservices in Spring. And while I try to give some high-level insight into what it means to work with microservices, I only scratch the surface. Other books from Manning such as "Cloud Native" (Cornelia Davis), "Spring Microservices in Action" (John Carnell), and "Microservices Patterns" (Chris Richardson) might be what you want if you want more focus on working with microservices.

Chintan Sanghavi wrote:I am really excited to see my much awaited title is out now. Many thanks Craig for helping many Spring developers to put Spring really in action over through past four editions.

Spring as well as project development landscape has changed a lot over the years. Would like to understand how this revised edition can help to understand and adopt to micro-service architecture quickly, as it's need of an hour for today's agile world ?

11 months ago

It depends on how you do configuration, but yes. Certainly, there's no way to do it with XML config. But if you are using JavaConfig and the bean you're creating requires a functional type, then there's no reason you couldn't just pass a lambda or method reference into the setter or constructor arg.

On the other hand, if you're asking if it's possible to declare a lambda as a bean, then I'm not so sure. I'd wonder what that would even look like. i suppose that it'd be possible to manually register a lambda as a bean by calling registerBean() on a given GenericApplicationContext, but I can't say that I've tried it. (I have used Lambdas to define a bean of a given type when calling registerBean(), but never have had the bean itself be defined as a Lambda.)


Will Myers wrote:Hi,
Does Spring 5 allow you to inject a lambda into a bean via configuration?

11 months ago

Spring has always embraced and integrated with other frameworks and libraries. In recent years, the one that comes immediately to mind is integration (under the Spring Cloud project) with the Netflix OSS projects, integration with Hashicorp's Vault, and support for both Reactor and RxJava types in Spring WebFlux controllers. There are certainly others...but these are the ones that I think of immediately...perhaps because they're the ones I work with the most and therefore find them most useful. Others might find other integrations more useful for their situation.

M Khalid wrote:Hi,

I think Spring is supporting many other frameworks and libraries and expanding its dependencies, can you please share some insight on which are the most recent and useful integration done with Spring/Spring Boot.

11 months ago
Rest-Repositories is for automatically creating REST endpoints for any repositories you may have created with Spring Data. If you are using Doring Data, it’s certainly worth looking into.

For creating your own REST endpoints, not necessarily associated with a Spring Data repository, you should pick either Spring MVC (Web) or Spring WebFlux (Reactive Web). The choice here hinges on whether you are ready to go reactive in your app.


Isaac Ferguson wrote:I am starting with the migration for it I am using the Spring Initializr to create the basic structure, but which one shoudl I use?

The project to migrate contains Rest Services and credentials. Which starter should I use ?

Regards, Isaac

11 months ago

For service discovery, I cover Netflix Eureka. It's still my favorite choice for that and Spring Cloud makes it super-easy to get started. As for load-balancing, I favor a client-side (e.g., service-consumer-side) load-balanced from Netflix called Ribbon. Again, Spring Cloud makes using Ribbon as easy as what you may already know about using RestTemplate (or WebClient if you're writing a reactive client).

Matt Campbell wrote:Hello Craig,

In your book, what tools/frameworks do you use/recommend for service discovery/load balancing? Do your examples use any specific cloud provider? Can we expect to have something fully configured by the end of the book?

11 months ago