2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.vid.testUtils;
23 import static com.fasterxml.jackson.module.kotlin.ExtensionsKt.jacksonObjectMapper;
24 import static java.util.function.Function.identity;
25 import static java.util.stream.Collectors.toList;
26 import static java.util.stream.Collectors.toMap;
27 import static org.apache.commons.beanutils.PropertyUtils.getPropertyDescriptors;
28 import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
29 import static org.apache.commons.text.CharacterPredicates.DIGITS;
30 import static org.apache.commons.text.CharacterPredicates.LETTERS;
31 import static org.apache.http.HttpVersion.HTTP_1_1;
32 import static org.mockito.ArgumentMatchers.any;
33 import static org.mockito.Mockito.RETURNS_DEFAULTS;
34 import static org.mockito.Mockito.mock;
35 import static org.mockito.Mockito.when;
36 import static org.mockito.Mockito.withSettings;
37 import static org.onap.vid.utils.KotlinUtilsKt.JACKSON_OBJECT_MAPPER;
38 import static org.onap.vid.utils.KotlinUtilsKt.JOSHWORKS_JACKSON_OBJECT_MAPPER;
39 import static org.testng.Assert.fail;
41 import com.fasterxml.jackson.databind.DeserializationFeature;
42 import com.fasterxml.jackson.databind.ObjectMapper;
43 import com.google.code.beanmatchers.BeanMatchers;
44 import com.google.common.collect.ImmutableList;
45 import io.joshworks.restclient.http.HttpResponse;
46 import java.beans.PropertyDescriptor;
47 import java.io.ByteArrayInputStream;
48 import java.io.IOException;
49 import java.io.InputStream;
50 import java.io.Serializable;
51 import java.lang.reflect.Field;
53 import java.nio.charset.StandardCharsets;
54 import java.util.Arrays;
55 import java.util.Iterator;
56 import java.util.List;
57 import java.util.function.Predicate;
58 import javax.ws.rs.client.Client;
59 import javax.ws.rs.client.Invocation;
60 import javax.ws.rs.client.WebTarget;
61 import javax.ws.rs.core.GenericType;
62 import javax.ws.rs.core.MediaType;
63 import javax.ws.rs.core.Response;
64 import org.apache.commons.beanutils.BeanUtils;
65 import org.apache.commons.io.IOUtils;
66 import org.apache.commons.lang3.exception.ExceptionUtils;
67 import org.apache.commons.lang3.reflect.FieldUtils;
68 import org.apache.commons.lang3.reflect.MethodUtils;
69 import org.apache.commons.text.RandomStringGenerator;
70 import org.apache.http.HttpResponseFactory;
71 import org.apache.http.entity.InputStreamEntity;
72 import org.apache.http.entity.StringEntity;
73 import org.apache.http.impl.DefaultHttpResponseFactory;
74 import org.apache.http.message.BasicStatusLine;
75 import org.apache.log4j.LogManager;
76 import org.apache.log4j.Logger;
77 import org.json.JSONArray;
78 import org.json.JSONObject;
79 import org.junit.Assert;
80 import org.mockito.InjectMocks;
81 import org.mockito.Mock;
82 import org.mockito.MockSettings;
83 import org.mockito.Mockito;
84 import org.mockito.MockitoAnnotations;
85 import org.mockito.invocation.InvocationOnMock;
86 import org.mockito.stubbing.Answer;
87 import org.mockito.stubbing.OngoingStubbing;
88 import org.onap.portalsdk.core.util.SystemProperties;
89 import org.onap.vid.asdc.AsdcCatalogException;
90 import org.onap.vid.asdc.beans.Service;
91 import org.onap.vid.mso.model.CloudConfiguration;
92 import org.springframework.core.env.Environment;
93 import org.testng.annotations.DataProvider;
96 * Created by Oren on 6/7/17.
98 public class TestUtils {
100 private static final Logger logger = LogManager.getLogger(TestUtils.class);
103 * The method compares between two jsons. the function assert that the actual object does not reduce or change the functionallity/parsing of the expected json.
104 * This means that if the expected JSON has a key which is null or the JSON doesn't have a key which contained in the expected JSON the assert will succeed and the will pass.
105 * For example : For JSON expected = {a:null} and actual {a:3} the test will pass
106 * Other example : For JSON expected = {a:3} and actual {a:null} the test will fail
108 * @param expected JSON
111 public static void assertJsonStringEqualsIgnoreNulls(String expected, String actual) {
112 if (expected == null || expected == JSONObject.NULL) {return;}
114 JSONObject expectedJSON = new JSONObject(expected);
115 JSONObject actualJSON = new JSONObject(actual);
116 Iterator<?> keys = expectedJSON.keys();
118 while( keys.hasNext() ) {
119 String key = (String)keys.next();
120 Object expectedValue = expectedJSON.get(key);
121 if (expectedValue == JSONObject.NULL){
125 Object actualValue = actualJSON.get(key);
127 if (expectedValue instanceof JSONObject) {
128 String expectedVal = expectedValue.toString();
129 String actualVal = actualValue.toString();
130 assertJsonStringEqualsIgnoreNulls(expectedVal, actualVal);
132 else if (expectedValue instanceof JSONArray) {
133 if (actualValue instanceof JSONArray) {
134 JSONArray expectedJSONArray = (JSONArray)expectedValue;
135 JSONArray actualJSONArray = (JSONArray)actualValue;
136 for (int i = 0; i < expectedJSONArray.length(); i++) {
137 String expectedItem = expectedJSONArray.get(i).toString();
138 String actualItem = actualJSONArray.get(i).toString();
139 if (expectedValue instanceof JSONObject)
140 assertJsonStringEqualsIgnoreNulls(expectedItem, actualItem);
144 fail("expected: " + expectedValue + " got:" + actualValue);
148 Assert.assertEquals("assertion fail for key:"+key, expectedValue, actualValue);
153 public static <T> T readJsonResourceFileAsObject(String pathInResource, Class<T> valueType) {
154 return readJsonResourceFileAsObject(pathInResource, valueType, false);
157 public static <T> T readJsonResourceFileAsObject(String pathInResource, Class<T> valueType, boolean failOnUnknownProperties) {
158 ObjectMapper objectMapper =
159 jacksonObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, failOnUnknownProperties);
162 return objectMapper.readValue(TestUtils.class.getResource(pathInResource), valueType);
163 } catch (IOException e) {
164 return ExceptionUtils.rethrow(e);
168 public static String readFileAsString(String pathInResource) {
170 return IOUtils.toString(TestUtils.class.getResource(pathInResource), "UTF-8");
171 } catch (IOException e) {
172 throw new RuntimeException(e);
176 public static String[] allPropertiesOf(Class<?> aClass) {
177 return Arrays.stream(getPropertyDescriptors(aClass))
178 .map(PropertyDescriptor::getDisplayName)
179 .toArray(String[]::new);
182 private static <T> List<String> allStringPropertiesOf(T object) {
183 return Arrays.stream(getPropertyDescriptors(object.getClass()))
184 .filter(descriptor -> descriptor.getPropertyType().isAssignableFrom(String.class))
185 .map(PropertyDescriptor::getDisplayName)
189 private static List<Field> allMockitoFieldsOf(Object object) {
190 final Predicate<Field> hasMockAnnotation = field -> field.getAnnotation(Mock.class) != null;
191 final Predicate<Field> hasInjectMocksAnnotation = field -> field.getAnnotation(InjectMocks.class) != null;
193 return Arrays.stream(FieldUtils.getAllFields(object.getClass()))
194 .filter(hasMockAnnotation.or(hasInjectMocksAnnotation))
199 * Calls MockitoAnnotations.initMocks after nullifying any field which is annotated @Mocke or @InjectMock.
200 * This makes a "hard rest" to any mocked state or instance. Expected to be invoked between any @Tests in class, by
201 * being called in TestNG's @BeforeMethod (or equivalently JUnit's @BeforeTest).
203 public static void initMockitoMocks(Object testClass) {
204 for (Field field : allMockitoFieldsOf(testClass)) {
206 // Write null to fields
207 FieldUtils.writeField(field, testClass, null, true);
208 } catch (ReflectiveOperationException e) {
209 ExceptionUtils.rethrow(e);
213 MockitoAnnotations.initMocks(testClass);
217 * Sets each String property with a value equal to the name of
218 * the property; e.g.: { name: "name", city: "city" }
221 * @return The modified object
223 public static <T> T setStringsInStringProperties(T object) {
225 final List<String> stringFields = allStringPropertiesOf(object);
227 BeanUtils.populate(object, stringFields.stream()
228 .collect(toMap(identity(), identity())));
231 } catch (Exception e) {
232 throw new RuntimeException(e);
236 public static void registerCloudConfigurationValueGenerator() {
237 BeanMatchers.registerValueGenerator(() -> new CloudConfiguration(
238 randomAlphabetic(7), randomAlphabetic(7), randomAlphabetic(7)
239 ), CloudConfiguration.class);
242 public static OngoingStubbing<InputStream> mockGetRawBodyWithStringBody(HttpResponse<String> httpResponse, String body) {
244 return when(httpResponse.getRawBody()).thenReturn(IOUtils.toInputStream(body, StandardCharsets.UTF_8.name()));
245 } catch (IOException e) {
246 ExceptionUtils.rethrow(e);
248 return null; //never shall get here
251 public static HttpResponse<String> createTestHttpResponse(int statusCode, String entity) throws Exception {
252 HttpResponseFactory factory = new DefaultHttpResponseFactory();
253 org.apache.http.HttpResponse response = factory.newHttpResponse(new BasicStatusLine(HTTP_1_1, statusCode, null), null);
254 if (entity != null) {
255 response.setEntity(new StringEntity(entity));
257 return new HttpResponse<>(response, String.class, null);
260 public static <T> HttpResponse<T> createTestHttpResponse(int statusCode, T entity, final Class<T> entityClass) throws Exception {
261 HttpResponseFactory factory = new DefaultHttpResponseFactory();
262 org.apache.http.HttpResponse response = factory.newHttpResponse(new BasicStatusLine(HTTP_1_1, statusCode, null), null);
263 if (entity != null) {
264 InputStream inputStream = IOUtils.toInputStream(JACKSON_OBJECT_MAPPER.writeValueAsString(entity), StandardCharsets.UTF_8.name());
265 response.setEntity(new InputStreamEntity(inputStream));
267 return new HttpResponse(response, entityClass, JOSHWORKS_JACKSON_OBJECT_MAPPER);
271 public static class JavaxRsClientMocks {
272 private final javax.ws.rs.client.Client fakeClient;
273 private final javax.ws.rs.client.Invocation.Builder fakeBuilder;
274 private final javax.ws.rs.client.Invocation fakeInvocation;
275 private final Response fakeResponse;
277 public javax.ws.rs.client.Client getFakeClient() {
281 public javax.ws.rs.client.Invocation.Builder getFakeBuilder() {
285 public Response getFakeResponse() {
289 public JavaxRsClientMocks() {
290 final MockSettings mockSettings = withSettings().defaultAnswer(new TriesToReturnMockByType());
292 fakeClient = mock(javax.ws.rs.client.Client.class, mockSettings);
293 fakeBuilder = mock(javax.ws.rs.client.Invocation.Builder.class, mockSettings);
294 fakeInvocation = mock(javax.ws.rs.client.Invocation.class, mockSettings);
295 fakeResponse = mock(Response.class, mockSettings);
296 final javax.ws.rs.client.WebTarget fakeWebTarget = mock(javax.ws.rs.client.WebTarget.class, mockSettings);
298 TriesToReturnMockByType.setAvailableMocks(
305 Mockito.when(fakeBuilder.get(any(Class.class))).thenReturn(null);
306 Mockito.when(fakeBuilder.get(any(GenericType.class))).thenReturn(null);
307 Mockito.when(fakeResponse.getStatus()).thenReturn(200);
308 Mockito.when(fakeResponse.getStatusInfo()).thenReturn(Response.Status.OK);
309 Mockito.when(fakeResponse.readEntity(Service.class)).thenReturn(null);
310 Mockito.when(fakeResponse.readEntity(InputStream.class)).thenReturn(new ByteArrayInputStream(new byte[]{}));
311 Mockito.when(fakeResponse.readEntity(String.class)).thenReturn(null);
316 inspired out from newer Mockito version
317 returns a mock from given list if it's a matching return-type
319 private static class TriesToReturnMockByType implements Answer<Object>, Serializable {
320 private final Answer<Object> defaultReturn = RETURNS_DEFAULTS;
321 private static List<Object> availableMocks = ImmutableList.of();
323 static void setAvailableMocks(Object... mocks) {
324 availableMocks = ImmutableList.copyOf(mocks);
327 public Object answer(InvocationOnMock invocation) throws Throwable {
328 Class<?> methodReturnType = invocation.getMethod().getReturnType();
330 return availableMocks.stream()
331 .filter(mock -> methodReturnType.isAssignableFrom(mock.getClass()))
332 //.peek(m -> logger.info("found a mock: " + m.getClass().getName()))
334 .orElse(defaultReturn.answer(invocation));
339 //The method mocks only some methods used in my case
340 //You may add some other when for your test here
341 public static Response mockResponseForJavaxClient(Client javaxClientMock) {
342 Response mockResponse = mock(Response.class);
343 WebTarget webTarget = mock(WebTarget.class);
344 Invocation.Builder builder = mock(Invocation.Builder.class);
345 when(javaxClientMock.target(any(URI.class))).thenReturn(webTarget);
346 when(webTarget.path(any())).thenReturn(webTarget);
347 when(webTarget.request(any(MediaType.class))).thenReturn(builder);
348 when(builder.headers(any())).thenReturn(builder);
349 when(builder.header(any(), any())).thenReturn(builder);
350 when(builder.get()).thenReturn(mockResponse);
355 public interface Test {
357 void apply() throws AsdcCatalogException;
360 public static void testWithSystemProperty(String key, String value, Test test) throws Exception {
361 SystemProperties systemProperties = new SystemProperties();
362 //use reflection to invoke protected method
363 Environment originalEnvironment = (Environment) MethodUtils
364 .invokeMethod(systemProperties, true, "getEnvironment");
367 Environment environment = mock(Environment.class);
368 systemProperties.setEnvironment(environment);
369 when(environment.getRequiredProperty(key)).thenReturn(value);
370 when(environment.containsProperty(key)).thenReturn(true);
374 systemProperties.setEnvironment(originalEnvironment);
378 private static RandomStringGenerator generator = new RandomStringGenerator.Builder()
379 .withinRange('0', 'z')
380 .filteredBy(LETTERS, DIGITS)
383 public static String generateRandomAlphaNumeric(int length) {
384 return generator.generate(length);
388 public static Object[][] trueAndFalse() {
389 return new Object[][]{{true}, {false}};