4

There is a type of statement in java that I could not understand or even find anything about through googling. I would like to share an example which I wrote but without understanding the language structure :

MvcResult result = this.mockMvc.perform(MockMvcRequestBuilders.post("/user_sessions/first")
                .contentType(MediaType.APPLICATION_JSON)
                .content("{\"username\":\""+username+"\",\"password\":\""+password+"\"}"))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn();

I don't understand what contentType , content, andExpect and andReturn are. They are obviously functions, but how can I call them like this. What class do they belong to? Overally I am very confused with the structure here.

İsmail Y.
  • 3,579
  • 5
  • 21
  • 29
Özüm
  • 55
  • 1
  • 3
  • It's called method chaining, `StringBuilder`'s `append` method allows you to do this as well. Basically the methods are returning an instance of `MvcResult` (`return this`), which allows you to chain method calls together. It's particularly popular in the builder pattern and saves a lot of typing... – MadProgrammer Sep 04 '14 at 08:14
  • You are invoking `contentType(...)` on the result of `this.mockMvc.perform(MockMvcRequestBuilders.post("/user_sessions/first")`, and so on and so on – amit Sep 04 '14 at 08:14

3 Answers3

9

What you are seeing here is called a fluent interface. A fluent interface is a mechanism to help improve the readability of code by cascading method calls. When you create a method the return value is that of the class, so in pseudo code this would be something like -

class Foo {
   private String baa;
   private String moo;
   public Foo setBaa( String baa ) {
     this.baa = baa;
     return this;
   }
   public Foo setMoo( String moo ) {
     this.moo = moo;
     return this;
   }
}

Note: the use of this as a return value to show that we are returning our current foo instance. This would allow the folliwng behaviour -

Foo test = new Foo();
test.setBaa( "baa" ).setMoo( "moo" );

If you would like more information on Fluent interfaces please have a look at http://en.wikipedia.org/wiki/Fluent_interface which gives a fairly in depth explanation.

Patrick
  • 33,984
  • 10
  • 106
  • 126
David Long
  • 181
  • 4
  • +1 For pointing out that "fluent interface" is the correct term for this sort of method design. It's a more specific situation that simple method chaining. – Duncan Jones Sep 04 '14 at 08:23
  • Although in fluent interfaces, it often **isn't** the same class that is returned. In order to step the user through the different stages of the fluent interface, different types are returned in order to provide different method options. – Duncan Jones Sep 04 '14 at 08:32
1

This is done for better readability. You could also write it as:

result = this.mockMvc.perform(MockMvcRequestBuilders.post("/user_sessions/first").contentType(MediaType.APPLICATION_JSON).content("{\"username\":\""+username+"\",\"password\":\""+password+"\"}")).andExpect(MockMvcResultMatchers.status().isOk()).andReturn();

All those methods return objects and the following methods are invoked on the returned objects.

stevecross
  • 5,588
  • 7
  • 47
  • 85
0

i think you are confused with your snippet

MvcResult result = this.mockMvc.perform(MockMvcRequestBuilders.post("/user_sessions/first")
                .contentType(MediaType.APPLICATION_JSON)
                .content("{\"username\":\""+username+"\",\"password\":\""+password+"\"}"))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn();

take a look at the first line it doesn't end with a semi colon which means that the line is not terminated.

as for the answer of SURESH ATTA. it is method chaining, they all belong to MvcResult and depending on the return type of the function.

you are confused that every line starts with dot then the function name. well this is probably because of your IDE's formatter. if the line is too long the formatter move the next function below it.

Ker p pag
  • 1,568
  • 12
  • 25