001/*
002 * Copyright 2012-2018 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.boot.test.json;
018
019import java.io.IOException;
020import java.io.Reader;
021
022import javax.json.bind.Jsonb;
023
024import org.springframework.beans.factory.ObjectFactory;
025import org.springframework.core.ResolvableType;
026import org.springframework.util.Assert;
027
028/**
029 * AssertJ based JSON tester backed by Jsonb. Usually instantiated via
030 * {@link #initFields(Object, Jsonb)}, for example: <pre class="code">
031 * public class ExampleObjectJsonTests {
032 *
033 *      private JsonbTester&lt;ExampleObject&gt; json;
034 *
035 *      &#064;Before
036 *      public void setup() {
037 *              Jsonb jsonb = JsonbBuilder.create();
038 *              JsonbTester.initFields(this, jsonb);
039 *      }
040 *
041 *      &#064;Test
042 *      public void testWriteJson() throws IOException {
043 *              ExampleObject object = // ...
044 *              assertThat(json.write(object)).isEqualToJson(&quot;expected.json&quot;);
045 *      }
046 *
047 * }
048 * </pre>
049 *
050 * See {@link AbstractJsonMarshalTester} for more details.
051 *
052 * @param <T> the type under test
053 * @author EddĂș MelĂ©ndez
054 * @since 2.0.0
055 */
056public class JsonbTester<T> extends AbstractJsonMarshalTester<T> {
057
058        private final Jsonb jsonb;
059
060        /**
061         * Create a new uninitialized {@link JsonbTester} instance.
062         * @param jsonb the Jsonb instance
063         */
064        protected JsonbTester(Jsonb jsonb) {
065                Assert.notNull(jsonb, "Jsonb must not be null");
066                this.jsonb = jsonb;
067        }
068
069        /**
070         * Create a new {@link JsonbTester} instance.
071         * @param resourceLoadClass the source class used to load resources
072         * @param type the type under test
073         * @param jsonb the Jsonb instance
074         * @see #initFields(Object, Jsonb)
075         */
076        public JsonbTester(Class<?> resourceLoadClass, ResolvableType type, Jsonb jsonb) {
077                super(resourceLoadClass, type);
078                Assert.notNull(jsonb, "Jsonb must not be null");
079                this.jsonb = jsonb;
080        }
081
082        @Override
083        protected String writeObject(T value, ResolvableType type) throws IOException {
084                return this.jsonb.toJson(value, type.getType());
085        }
086
087        @Override
088        protected T readObject(Reader reader, ResolvableType type) throws IOException {
089                return this.jsonb.fromJson(reader, type.getType());
090        }
091
092        /**
093         * Utility method to initialize {@link JsonbTester} fields. See {@link JsonbTester
094         * class-level documentation} for example usage.
095         * @param testInstance the test instance
096         * @param jsonb the Jsonb instance
097         */
098        public static void initFields(Object testInstance, Jsonb jsonb) {
099                new JsonbFieldInitializer().initFields(testInstance, jsonb);
100        }
101
102        /**
103         * Utility method to initialize {@link JsonbTester} fields. See {@link JsonbTester
104         * class-level documentation} for example usage.
105         * @param testInstance the test instance
106         * @param jsonb an object factory to create the Jsonb instance
107         */
108        public static void initFields(Object testInstance, ObjectFactory<Jsonb> jsonb) {
109                new JsonbTester.JsonbFieldInitializer().initFields(testInstance, jsonb);
110        }
111
112        /**
113         * {@link FieldInitializer} for Jsonb.
114         */
115        private static class JsonbFieldInitializer extends FieldInitializer<Jsonb> {
116
117                protected JsonbFieldInitializer() {
118                        super(JsonbTester.class);
119                }
120
121                @Override
122                protected AbstractJsonMarshalTester<Object> createTester(
123                                Class<?> resourceLoadClass, ResolvableType type, Jsonb marshaller) {
124                        return new JsonbTester<>(resourceLoadClass, type, marshaller);
125                }
126
127        }
128
129}