MockInjection.java revision e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7
1/*
2 * Copyright (c) 2007 Mockito contributors
3 * This program is made available under the terms of the MIT License.
4 */
5
6package org.mockito.internal.configuration.injection;
7
8import java.lang.reflect.Field;
9import java.util.Collections;
10import java.util.HashSet;
11import java.util.Set;
12
13import static org.mockito.internal.util.Checks.checkItemsNotNull;
14import static org.mockito.internal.util.Checks.checkNotNull;
15import static org.mockito.internal.util.collections.Sets.newMockSafeHashSet;
16
17/**
18 * Internal injection configuration utility.
19 *
20 * <p>
21 * Allow the user of this class to configure the way the injection of mocks will happen.
22 * </p>
23 *
24 */
25public class MockInjection {
26
27    /**
28     * Create a new configuration setup for a field
29     *
30     *
31     * @param field Field needing mock injection
32     * @param ofInstance Instance owning the <code>field</code>
33     * @return New configuration builder
34     */
35    public static OngoingMockInjection onField(Field field, Object ofInstance) {
36        return new OngoingMockInjection(field, ofInstance);
37    }
38
39    /**
40     * Create a new configuration setup for fields
41     *
42     *
43     * @param fields Fields needing mock injection
44     * @param ofInstance Instance owning the <code>field</code>
45     * @return New configuration builder
46     */
47    public static OngoingMockInjection onFields(Set<Field> fields, Object ofInstance) {
48        return new OngoingMockInjection(fields, ofInstance);
49    }
50
51    /**
52     * Ongoing configuration of the mock injector.
53     */
54    public static class OngoingMockInjection {
55        private Set<Field> fields = new HashSet<Field>();
56        private Set<Object> mocks = newMockSafeHashSet();
57        private Object fieldOwner;
58        private MockInjectionStrategy injectionStrategies = MockInjectionStrategy.nop();
59        private MockInjectionStrategy postInjectionStrategies = MockInjectionStrategy.nop();
60
61        private OngoingMockInjection(Field field, Object fieldOwner) {
62            this(Collections.singleton(field), fieldOwner);
63        }
64
65        private OngoingMockInjection(Set<Field> fields, Object fieldOwner) {
66            this.fieldOwner = checkNotNull(fieldOwner, "fieldOwner");
67            this.fields.addAll(checkItemsNotNull(fields, "fields"));
68        }
69
70        public OngoingMockInjection withMocks(Set<Object> mocks) {
71            this.mocks.addAll(checkNotNull(mocks, "mocks"));
72            return this;
73        }
74
75        public OngoingMockInjection tryConstructorInjection() {
76            injectionStrategies.thenTry(new ConstructorInjection());
77            return this;
78        }
79
80        public OngoingMockInjection tryPropertyOrFieldInjection() {
81            injectionStrategies.thenTry(new PropertyAndSetterInjection());
82            return this;
83        }
84
85        public OngoingMockInjection handleSpyAnnotation() {
86            postInjectionStrategies.thenTry(new SpyOnInjectedFieldsHandler());
87            return this;
88        }
89
90        public void apply() {
91            for (Field field : fields) {
92                injectionStrategies.process(field, fieldOwner, mocks);
93                postInjectionStrategies.process(field, fieldOwner, mocks);
94            }
95        }
96    }
97}
98