In this example we'll show you how to mock Security Context and Authentication in Spring boot test. This could be needed in case that in your code you're for example getting some value from your token like it was a case for me. I needed the user_name parameter nested in decoded details of Oauth2AuthenticationDetails. We'll be using Mockito and it's mock and when methods to firstly mock Oauth2AuthenticationDetails and then build up until we get to the SecurityContextHolder.

Here's the code example:

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;


.....
Map<String, Object> details = new HashMap<String, Object>();
details.put("user_name", "someusername");
OAuth2AuthenticationDetails oauthDetails = mock(OAuth2AuthenticationDetails.class);
when(oauthDetails.getDecodedDetails()).thenReturn(details);
Authentication authentication = mock(Authentication.class);
when(authentication.getDetails()).thenReturn(oauthDetails);

SecurityContext securityContext = mock(SecurityContext.class);
when(securityContext.getAuthentication()).thenReturn(authentication);
SecurityContextHolder.setContext(securityContext);
......

 

 1. Introduction

In this tutorial, we'll show you how to test RestController in Spring. To test the controller, one of the most popular options is to use Mockito and MockMvc. In this example, we'll have two model classes, Cat and Sighting. So, the idea is to whenever Cat is spotted, one Sighting object is created that contains a reference to Cat and image of spotted cat. 

2. Maven dependencies

You'll only need spring-boot-starter-test artifact. 

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
  <scope>test</scope>
</dependency>

3. Controller test

Here you'll see how to write two tests - one should test a situation where a list of returned sighting is empty, and we're just checking if we got 200 response code. Other will test situation when there's content in the Page. We'll mock service response by annotating it with @MockBean.

Since we're mocking response here, and response is Paginated, you'll also see here how to mock Page response:

Page<Sighting> sightingPageMockResponse = new PageImpl<Sighting>(new ArrayList<Sighting>());

Here's full code with two controller tests:

import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;

import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;

import com.catspotservice.controller.SightingController;
import com.catspotservice.service.SightingService;
import com.model.catspot.Cat;
import com.model.catspot.Sighting;

@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
@SpringBootTest
public class SightingControllerTest {

	@Mock
	SightingController sightingController;

	@Autowired
	private MockMvc mockMvc;

	@MockBean
	private SightingService sightingService;

	Sighting sighting1;
	Sighting sighting2;
	List<Sighting> sightings;

	@Before
	public void createTestSightings() {
		Cat cat1 = new Cat();
		cat1.setId(1l);
		cat1.setName("black cat");
		cat1.setDescription("domestic black cat");
		cat1.setImage("location to some black cat image");
		Cat cat2 = new Cat();
		cat2.setId(2l);
		cat2.setName("orange cat");
		cat2.setDescription("some orange cat");
		cat2.setImage("path to some orange cat image");
		sighting1 = new Sighting();
		sighting1.setId(1l);
		sighting1.setCat(cat1);
		sighting2 = new Sighting();
		sighting2.setId(2l);
		sighting2.setCat(cat2);
		sighting2.setImage("some image2");
		sightings = new ArrayList<Sighting>();
		sightings.add(sighting1);
		sightings.add(sighting2);
	}

	@Test
	public void testGetSightings_ValidRequest_NoResponse() throws Exception {

		Page<Sighting> sightingPageMockResponse = new PageImpl<Sighting>(new ArrayList<Sighting>());
		when(sightingService.findSightings(1l, 1, 1)).thenReturn(sightingPageMockResponse);

		mockMvc.perform(
				MockMvcRequestBuilders.get("/api/public/sighting?catId=1&page=1&size=1").accept(MediaType.ALL))
				.andExpect(MockMvcResultMatchers.status().isOk()).andReturn();
	}

	@Test
	public void testGetSightings_ValidRequest_PageResponse() throws Exception {
		Page<Sighting> sightingPageMockResponse = new PageImpl<Sighting>(sightings);
		when(sightingService.findSightings(1l, 1, 1)).thenReturn(sightingPageMockResponse);
		mockMvc.perform(MockMvcRequestBuilders.get("/api/public/sighting?catId=1&page=1&size=1")
				.accept(MediaType.ALL).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultHandlers.print())
				.andExpect(MockMvcResultMatchers.status().isOk()).andExpect(jsonPath("$.totalPages").value(1))
				.andExpect(jsonPath("$.totalElements").value(2)).andReturn();
	}
}

Notice that we annotated Test class with:

@Runner(SpringRunner.class)
@AutoConfigureSpringMvc
@SpringBootTest

To make MockMvc call some service use MockMvcRequestBuilders.httpMethod.

If you want to make MockMvc write response it got to the console use .andDo(MockMvcResultHandlers.print()) just before you start expecting params from the response.

Validate HTML with Rest Assured

Validate HTML with Rest Assured with sample code

This tutorial will guide you through the validation of HTML using Rest Assured. It's not so common, but Rest Assured has support for HTML. We'll show the working example where we get the first page from https://www.amazon.com and validate some elements on the page we got. 

We'll test Amazon search, so first, we'll write search terms in the search box and open Chrome Developer Tools (you have a similar tool on Firefox if you're using it). In Developer Tools, Network tab, you'll see the URL that returns an HTML page. So, we'll try to call this URL, just this time through the Rest Assured code where we'll see how to validate HTML with Rest Assured.

Goal

So, url we see there is https://www.amazon.com/s/ref=nb_sb_noss_1?url=search-alias%3Daps&field-keywords=phone+holder+for+car

As you can see, this url has two params:

  • url with value search-alias=aps (this "=" symbol is encoded as %3D)
  • field-keywords - we decided for our search term to be "phone holder for car"

https://www.amazon.com/s/ref=nb_sb_noss_1?url=search-alias%3Daps&field-keywords=phone+holder+for+car

Validate HTML with Rest Assured

So, we'll use Postman (you can check page source, or locate title in Response tab in Developer tools) for better preview of HTML and we'll locate title tag:

postman amazon get

Implementation

Test for this situation will be:

package restassured.html.demo;

import static io.restassured.RestAssured.given;
import static io.restassured.path.xml.XmlPath.CompatibilityMode.HTML;
import static org.testng.Assert.assertEquals;

import org.testng.annotations.Test;

import io.restassured.http.ContentType;
import io.restassured.path.xml.XmlPath;
import io.restassured.response.Response;

public class SearchBoxTest {

	@Test
	public void searchBoxTest() {
		Response response = given().param("url", "search-alias=aps").param("field-keywords", "phone holder for car")
				.when().get(" https://www.amazon.com/s/ref=nb_sb_noss_1").then().contentType(ContentType.HTML).extract()
				.response();
		assertEquals(response.getStatusCode(), 200);
		XmlPath htmlPath = new XmlPath(HTML, response.getBody().asString());
		assertEquals(htmlPath.getString("html.head.title"), "Amazon.com: phone holder for car");
	}
}

You'll notice that we're converting received HTML into XmlPath because it's the easiest way to access XML nodes within HTML through Java code.

It's pretty straightforward to validate title because we know that the title tag is located under the html->head tag, so we will show another a bit more complicated example. As you can see in the above image from Amazon, the search box on the resulting page contains our search terms. So, we'll use the element inspector to locate the search box and text within it. Right-click and Copy/Copy full XPath. This path locates elements within the HTML file. 

chrome developer tools amazon get call

Path you'll get will be something like this "/html/body/div[1]/header/div/div[1]/div[3]/div/form/div[3]/div[1]/input". Replace "/" with dots since they are node separators accepted by XmlPath. In the end you should have something like this: html.body.div[1].header.div.div[1].div[3].div.form.div[3].div[1].input. Pay attention to indexes of array elements, it's possible you would need to lower it by 1 because indexes in java start from 0.

If you're here because you want to start with Selenium, you're in the right place.

This quick start tutorial is intended for complete beginners (no prior Java knowledge is needed), so we will cover project creation, manually add libraries and write code for one simple test scenario that will be executed in Google Chrome.

You'll also learn what are some basic elements of Selenium. If you prefer watching over reading when you study, scroll to the end of this tutorial, we also prepared a quick video guide. So, keep in mind this is plain, simple example without any additional frameworks and optimizations. After you catch up with these basic things, you can optimize, mavenize, etc your project as you wish. 

Newsletter

Please enable the javascript to submit this form

Latest