RestAssured Java: How to get header user and pass from setup method - java

I have a class which has the following
package com.example.misc;
import com.jayway.restassured.RestAssured;
import com.jayway.restassured.authentication.PreemptiveBasicAuthScheme;
import org.junit.BeforeClass;
public class QueryEndpoint {
#BeforeClass
public static void setup() {
RestAssured.port = 8010;
PreemptiveBasicAuthScheme authScheme = new PreemptiveBasicAuthScheme();
authScheme.setUserName("username123");
authScheme.setPassword("password123");
RestAssured.authentication = authScheme;
String basePath;
basePath = "/api/version1/";
RestAssured.basePath = basePath;
String baseHost;
baseHost = "http://localhost";
RestAssured.baseURI = baseHost;
}
}
Then in another class, I have a test...
package com.example.tests;
import com.example.misc.QueryEndpoint;
import org.junit.Test;
import static com.jayway.restassured.RestAssured.given;
import static org.hamcrest.Matchers.equalTo;
public class ApiTest extends QueryEndpoint{
#Test
public void verifyTopLevelURL() {
given()
.auth(). preemptive().basic("username", "password")// THIS LINE DON'T WORK, need to add here something?
.contentType("application/json")
.when().get("/123456789").then()
.body("fruit",equalTo("123456789"))
.body("fruit.apple",equalTo(37))
.body("fruit.red",equalTo("apple"))
.statusCode(200);
}
My Question is: How do I use the header + user + pass set in the method setup() and call that to be used in my test verifyTopLevelURL.

You can directly use static variable approach as you are inheriting ApiTest Class from QueryEndpoint Class. Here is the code snippet :
Your QueryEndpoint Class :
package com.example.misc;
import com.jayway.restassured.RestAssured;
import com.jayway.restassured.authentication.PreemptiveBasicAuthScheme;
import org.junit.BeforeClass;
public class QueryEndpoint {
static String userName = "username123";
static String password = "password123";
#BeforeClass
public static void setup() {
RestAssured.port = 8010;
PreemptiveBasicAuthScheme authScheme = new PreemptiveBasicAuthScheme();
authScheme.setUserName(userName);
authScheme.setPassword(password);
RestAssured.authentication = authScheme;
String basePath;
basePath = "/api/version1/";
RestAssured.basePath = basePath;
String baseHost;
baseHost = "http://localhost";
RestAssured.baseURI = baseHost;
}
}
Your ApiTest Class :
package com.example.tests;
import com.example.misc.QueryEndpoint;
import org.junit.Test;
import static com.jayway.restassured.RestAssured.given;
import static org.hamcrest.Matchers.equalTo;
public class ApiTest extends QueryEndpoint{
#Test
public void verifyTopLevelURL() {
given()
.auth(). preemptive().basic(userName, password)
.contentType("application/json")
.when().get("/123456789").then()
.body("fruit",equalTo("123456789"))
.body("fruit.apple",equalTo(37))
.body("fruit.red",equalTo("apple"))
.statusCode(200);
}
You can do same thing with headers too. Hope this helped.

Related

mockito when interact with each other in different method

I have a short piece of code and two unit test. Strangely when I launch the test separately they works well but when I launch them together it look like the second method use the "when" of the first method.
Tested method :
public ProductIssuer update(ProductIssuer productIssuer) {
findById(productIssuer.getId())
.orElseThrow(() -> new B4FinanceException(ErrorCode.USER_NOT_FOUND, "Please provide an existing user"));
return productIssuerRepository.save(productIssuer);
}
The tests :
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
public class ProductIssuerServiceTest {
#InjectMocks
private static ProductIssuerService productIssuerService;
#Mock
private static ProductIssuerRepository productIssuerRepository;
public static final UUID DEFAULT_UUID = UUID.fromString("b8fc499a-2084-11e8-b467-0ed5f89f0000");
private static final String DEFAULT_NAME = "productIssuer Name";
#BeforeEach
public void setup() {
MockitoAnnotations.initMocks(this);
}
#Test
public void updateNotFoundThrowException() {
ProductIssuer productIssuer = new ProductIssuer();
productIssuer.setName(DEFAULT_NAME);
when(productIssuerRepository.findById(any())).thenReturn(Optional.empty());
assertThatExceptionOfType(B4FinanceException.class).isThrownBy(() -> productIssuerService.update(productIssuer));
}
#Test
public void update() {
ProductIssuer productIssuer = new ProductIssuer();
productIssuer.setName(DEFAULT_NAME);
productIssuer.setId(DEFAULT_UUID);
when(productIssuerRepository.findById(any())).thenReturn(Optional.of(productIssuer));
when(productIssuerRepository.save(any())).thenReturn(productIssuer);
productIssuerService.update(productIssuer);
}
}
The result is ok for the first test (updateNotFoundThrowException) but for the second test I got a "Please provide an existing user" error.

How does a Micronaut controller determine its base URL

For example if I have the following controller:
import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.*;
#Controller("/test")
public class TestController {
#Get()
#Produces(MediaType.TEXT_PLAIN)
public String index() {
// How should this be implemented?
return "???";
}
}
and I run it on my-server, then I would like the index method to return http://my-server:8080.
Asof Micronaut V1.2.0, you can use the HttpHostResolver interface, for example:
import io.micronaut.http.*;
import io.micronaut.http.annotation.*;
import io.micronaut.http.server.util.HttpHostResolver;
import io.micronaut.web.router.RouteBuilder;
#Controller("/test")
public class TestController {
private final HttpHostResolver httpHostResolver;
private final RouteBuilder.UriNamingStrategy uriNamingStrategy;
public TestController(
HttpHostResolver httpHostResolver,
RouteBuilder.UriNamingStrategy uriNamingStrategy
) {
this.httpHostResolver = httpHostResolver;
this.uriNamingStrategy = uriNamingStrategy;
}
#Get()
#Produces(MediaType.TEXT_PLAIN)
public String index(HttpRequest httpRequest) {
return httpHostResolver.resolve(httpRequest) +
uriNamingStrategy.resolveUri(TestController.class);
}
}
This seems to work:
import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.*;
import io.micronaut.runtime.server.EmbeddedServer;
import io.micronaut.web.router.RouteBuilder;
import java.net.*;
#Controller("/test")
public class TestController {
protected final String baseUrl;
public TestController(EmbeddedServer embeddedServer, RouteBuilder.UriNamingStrategy uns)
throws MalformedURLException {
final String host = embeddedServer.getHost();
final int port = embeddedServer.getPort();
final String file = uns.resolveUri(TestController.class);
baseUrl = new URL("http", host, port, file).toString();
}
#Get()
#Produces(MediaType.TEXT_PLAIN)
public String index() {
return baseUrl;
}
}
I'm not sure whether it's idiomatic, or whether it works in all cases. If someone posts a better answer I'll accept that.
If you want the controller to respond at / then use #Controller("/") instead of #Controller("/test").
package com.tech.api;
import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.PathVariable;
import java.util.List;
import javax.inject.Inject;
#Controller("/")
public class ModelDefinitionsApi {
#Get(uri="/modelName", produces = MediaType.APPLICATION_JSON)
public String getModel(#PathVariable String modelName) {
return "modelName";
}
}
http://my-server:8080 => main controller url
http://my-server:8080/modelName => for getModel method

How to have a RestTemplate encode all characters with UriComponents and EncodingMode.VALUES_ONLY?

I want my REST client, using Spring Web's RestTemplate, to %-encode all special characters in URL parameters, not only illegal characters. Spring Web's documentation states that the encoding method can be changed by configuring the DefaultUriBuilderFactory used by RestTemplate with setEncodingMode(EncodingMode.VALUES_ONLY):
String baseUrl = "http://example.com";
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl)
factory.setEncodingMode(EncodingMode.VALUES_ONLY);
RestTemplate restTemplate = new RestTemplate();
restTemplate.setUriTemplateHandler(factory);
this should "apply UriUtils.encode(String, Charset) to each URI variable value" which in turn will "encode all characters that are either illegal, or have any reserved meaning, anywhere within a URI, as defined in RFC 3986".
I wrote the following test case to try and demonstrate that changing to EncodingMode.VALUES_ONLY does not have the desired effect. (executing it with dependencies org.springframework.boot:spring-boot-starter:2.0.3.RELEASE, org.springframework:spring-web:5.0.7.RELEASE, org.springframework.boot:spring-boot-starter-test:2.0.3.RELEASE)
package com.example.demo.encoding;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
import java.nio.charset.StandardCharsets;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.client.RestClientTest;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.client.MockRestServiceServer;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.DefaultUriBuilderFactory;
import org.springframework.web.util.DefaultUriBuilderFactory.EncodingMode;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.web.util.UriUtils;
#RunWith(SpringRunner.class)
#RestClientTest(DemoClient.class)
public class EncodingTest {
#Autowired private MockRestServiceServer mockServer;
#Autowired private DemoClient client;
#Test
public void encodeAllCharactersInParameter() {
mockServer.expect(requestTo(encodedQueryUrl("https://host", "+:/")))
.andExpect(method(HttpMethod.GET))
.andRespond(withSuccess());
client.request("https://host", "+:/");
mockServer.verify();
}
private String encodedQueryUrl(final String baseUrl, final String parameter) {
return String.format("%s?parameter=%s", baseUrl,
UriUtils.encode(parameter, StandardCharsets.UTF_8));
}
}
#Component
class DemoClient {
private final RestTemplate restTemplate;
public DemoClient(RestTemplateBuilder restTemplateBuilder) {
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory();
factory.setEncodingMode(EncodingMode.VALUES_ONLY);
restTemplateBuilder.uriTemplateHandler(factory);
this.restTemplate = restTemplateBuilder.build();
}
public Object request(final String url, final String parameter) {
UriComponents queryUrl = UriComponentsBuilder.fromHttpUrl(url)
.queryParam("parameter", parameter).build().encode();
return restTemplate.getForObject(queryUrl.toUri(), Object.class);
}
}
This test fails with java.lang.AssertionError: Request URI expected:<https://host?parameter=%2B%3A%2F> but was:<https://host?parameter=+:/>. So what am I doing wrong? Is it a bug in Spring Framework or does MockRestServiceServer decode URLs before verifying expectations?
Two issues in the example:
One, the request method prepares and encodes a java.net.URI externally, so the RestTemplate is not the one preparing it. You need to pass a URI template with a URI variable in it, so that the RestTemplate has a chance to prepare the URI and do the encoding. For example:
public Object request(final String url, final String parameter) {
String urlString = UriComponentsBuilder.fromHttpUrl(url)
.queryParam("parameter", "{param}")
.build()
.toUriString();
return restTemplate.getForObject(urlString, Object.class, parameter);
}
Or simply have request take the URI template string:
public Object request(final String url) {
return restTemplate.getForObject(url, Object.class, parameter);
}
// then invoke like this...
request("https://host?parameter={param}");
Two, the RestTemplateBuilder#uriTemplateHandler returns a new instance, so you need to use that for the configuration change to take effect:
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory();
factory.setEncodingMode(EncodingMode.VALUES_ONLY);
restTemplateBuilder = restTemplateBuilder.uriTemplateHandler(factory); // <<<< see here
this.restTemplate = restTemplateBuilder.build();
It works as expected with the above changes.
Note that https://jira.spring.io/browse/SPR-17039 will make it easier to also achieve the same effect using UriComponentsBuilder, so check for updates there.
Corrected example:
package com.example.demo.encoding;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
import java.nio.charset.StandardCharsets;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.client.RestClientTest;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.client.MockRestServiceServer;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.DefaultUriBuilderFactory;
import org.springframework.web.util.DefaultUriBuilderFactory.EncodingMode;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.web.util.UriUtils;
#RunWith(SpringRunner.class)
#RestClientTest(DemoClient.class)
public class EncodingTest {
#Autowired private MockRestServiceServer mockServer;
#Autowired private DemoClient client;
#Test
public void encodeAllCharactersInParameter() {
mockServer.expect(requestTo(encodedQueryUrl("https://host", "+:/")))
.andExpect(method(HttpMethod.GET))
.andRespond(withSuccess());
client.request("https://host", "+:/");
mockServer.verify();
}
private String encodedQueryUrl(final String baseUrl, final String parameter) {
return String.format("%s?parameter=%s", baseUrl,
UriUtils.encode(parameter, StandardCharsets.UTF_8));
}
}
#Component
class DemoClient {
private final RestTemplate restTemplate;
public DemoClient(RestTemplateBuilder restTemplateBuilder) {
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory();
factory.setEncodingMode(EncodingMode.VALUES_ONLY);
this.restTemplate = restTemplateBuilder.uriTemplateHandler(factory).build();
}
public Object request(final String url, final String parameter) {
String urlString = UriComponentsBuilder.fromHttpUrl(url)
.queryParam("parameter", "{param}").build().toUriString();
return restTemplate.getForObject(urlString, Object.class, parameter);
}
}

Mocking final class with parameterized constructor

I have a final class as below
public class firstclass{
private String firstmethod(){
return new secondclass("params").somemethod();
}
}
public final class secondclass{
secondclass(String params){
//some code
}
public String somemethod(){
// some code
return somevariable";
}
}
I have to here test first class so I have mocked this as below
secondclass classMock = PowerMockito.mock(secondclass .class);
PowerMockito.whenNew(secondclass .class).withAnyArguments().thenReturn(classMock);
Mockito.doReturn("test").when(classMock).somemethod();
But it is not mocking as I expected can anyone help me?
The method firstclass.firstmethod() is private method. So try to test this method through public method in which it is getting called.
You can mock SecondClass and its final method using #RunWith(PowerMockRunner.class) and #PrepareForTest(SecondClass.class) annotations.
Please see below the working code:
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
#PrepareForTest(SecondClass.class)
public class FirstClassTest{
#Before
public void init() {
}
#After
public void clear() {
}
#Test
public void testfirstmethod() throws Exception{
SecondClass classMock = PowerMockito.mock(SecondClass.class);
PowerMockito.whenNew(SecondClass.class).withAnyArguments().thenReturn(classMock);
Mockito.doReturn("test").when(classMock).somemethod();
new FirstClass().firstmethod();
}
}
Libraries used:

impossible to import android.content.res.Resources

I can't find how to import android.content.res.Resources;
Here is my code:
package com.mycompany.fortune;
import com.google.gson.JsonObject;
import retrofit.Callback;
import retrofit.RestAdapter;
import retrofit.RetrofitError;
import retrofit.client.Response;
import android.content.res.Resources; //This don't work
import retrofit.http.GET;
import java.util.List;
import java.util.Random;
public class FortuneClient {
private static final String API_URL = "http://www.myurl.fr";
private interface FortuneService {
#GET("/test.php")
void getFortune(Callback<JsonObject> callback);
}
public static class OnFortuneListener {
public void onFortune(String fortune) {
}
}
private static Random rng = new Random();
private FortuneService service;
public FortuneClient() {
RestAdapter adapter = new RestAdapter.Builder()
.setEndpoint(API_URL)
.build();
service = adapter.create(FortuneService.class);
}
public void getFortune(final OnFortuneListener listener) {
service.getFortune(new Callback<JsonObject>() {
#Override
public void success(JsonObject json, Response response) {
String test = json.getAsJsonObject("0").getAsJsonObject("title").toString();
String test2 = json.getAsJsonObject("0").getString('title');
listener.onFortune(test2);
}
#Override
public void failure(RetrofitError error) {
listener.onFortune(error.toString());
}
});
}
}
the error is: "Error:(8, 26) Gradle: error: package android.content.res does not exist"
What I tried:
-Make, remake, build, clean, rebuild,
-Invalidate cache and restart,
-Verify the java/sdk/jdk positions,
-Stupid things on the gradle/xml files.
This import android.content.res.Resources; //This don't work is used in your application code to access the resources. To Access any particular resource you should pass the context to this class atleast .

Categories

Resources