Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,18 @@ TestDto:
- myPrivateField: String: null
- myPublicField: int: 0

### Omit all fields for type
```java
var result = fixture.build(TestDto.class)
.without(String.class)
.without(int.class)
.create();
```
#### Sample Result
TestDto:
- myPrivateField: String: null
- myPublicField: int: 0

#### Note
Primitives will receive their default-value, classes will be `null`.

Expand Down
3 changes: 2 additions & 1 deletion src/main/java/com/github/nylle/javafixture/Context.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.nylle.javafixture;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

Expand All @@ -24,7 +25,7 @@ public Context(Configuration configuration, Map<SpecimenType<?>, Object> predefi
}

this.configuration = configuration;
this.cache = new ConcurrentHashMap<>(predefinedInstances);
this.cache = new HashMap<>(predefinedInstances);
}

public Configuration getConfiguration() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,7 @@ public interface ISpecimenBuilder<T> {
<U> ISpecimenBuilder<T> with(SpecimenType<U> type, U value);

ISpecimenBuilder<T> without(String fieldName);

<U> ISpecimenBuilder<T> without(Class<U> fieldName);
}

6 changes: 4 additions & 2 deletions src/main/java/com/github/nylle/javafixture/Reflector.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,10 @@ public Annotation[] getFieldAnnotations(Field field) {

public void setField(Field field, Object value) {
try {
field.setAccessible(true);
field.set(instance, value);
if (!field.getType().isPrimitive() || value != null) {
field.setAccessible(true);
field.set(instance, value);
}
} catch (SecurityException e) {
throw new SpecimenException(format("Unable to access field %s on object of type %s", field.getName(), type.getName()), e);
} catch (IllegalAccessException | InaccessibleObjectException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import java.util.stream.IntStream;
import java.util.stream.Stream;
Expand All @@ -15,7 +14,7 @@ public class SpecimenBuilder<T> implements ISpecimenBuilder<T> {
private final List<Consumer<T>> functions = new LinkedList<>();
private final List<String> ignoredFields = new LinkedList<>();
private final Map<String, Object> customFields = new HashMap<>();
private final Map<SpecimenType<?>, Object> predefinedInstances = new ConcurrentHashMap<>();
private final Map<SpecimenType<?>, Object> predefinedInstances = new HashMap<>();

private final SpecimenType<T> type;
private final Configuration configuration;
Expand Down Expand Up @@ -129,6 +128,12 @@ public ISpecimenBuilder<T> without(final String fieldName) {
return this;
}

@Override
public <U> ISpecimenBuilder<T> without(Class<U> fieldName) {
predefinedInstances.put(SpecimenType.fromClass(fieldName), null);
return this;
}

T construct() {
return new SpecimenFactory(new Context(configuration)).build(type).create(new CustomizationContext(List.of(), Map.of(), true), new Annotation[0]);
}
Expand Down
12 changes: 12 additions & 0 deletions src/test/java/com/github/nylle/javafixture/FixtureTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,18 @@ void canOmitPrivateField() {
assertThat(result.getHello()).isNull();
}

@Test
void canOmitFieldsOfClassByType() {
var fixture = new Fixture(configuration);

TestPrimitive result = fixture.build(TestPrimitive.class).without(String.class)
.without(int.class).create();

assertThat(result.getHello()).isNull();
assertThat(result.getInteger()).isNotNull();
assertThat(result.getPrimitive()).isZero();
}

@Test
void canCustomizeOptional() {
Fixture fixture = new Fixture(configuration);
Expand Down
48 changes: 48 additions & 0 deletions src/test/java/com/github/nylle/javafixture/ReflectorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
Expand Down Expand Up @@ -99,10 +100,55 @@ void omittingDuplicateFields() {
@DisplayName("when setting a field via reflection")
class SetField {

private String stringField;
private int primitiveField;

@DisplayName("an Object field can be set")
@Test
void setObject() throws Exception {
var field = this.getClass().getDeclaredField("stringField");
var sut = new Reflector<>(this, new SpecimenType<>(){});
sut.setField(field, "new value");

assertThat(stringField).isEqualTo("new value");
}

@DisplayName("an Object field can be set to null")
@Test
void setObjectToNull() throws Exception {
stringField = "before";
var field = this.getClass().getDeclaredField("stringField");
var sut = new Reflector<>(this, new SpecimenType<>(){});
sut.setField(field, null);

assertThat(stringField).isNull();
}

@DisplayName("a primitive field can be set")
@Test
void setPrimitiveField() throws Exception {
var field = this.getClass().getDeclaredField("primitiveField");
var sut = new Reflector<>(this, new SpecimenType<>(){});
sut.setField(field, 4);

assertThat(primitiveField).isEqualTo(4);
}

@DisplayName("setting a primitive field to null keeps the default value")
@Test
void setPrimitiveFieldToNull() throws Exception {
var field = this.getClass().getDeclaredField("primitiveField");
var sut = new Reflector<>(this, new SpecimenType<>(){});
sut.setField(field, null);

assertThat(primitiveField).isEqualTo(0);
}

@DisplayName("an IllegalAccessException is turned into a SpecimenException")
@Test
void catchIllegalAccessException() throws Exception {
var mockedField = Mockito.mock(Field.class);
doReturn(this.getClass()).when(mockedField).getType();
var sut = new Reflector<>("", new SpecimenType<>(){});
doThrow(new IllegalAccessException("expected")).when(mockedField).set(any(), any());

Expand All @@ -114,6 +160,7 @@ void catchIllegalAccessException() throws Exception {
@Test
void catchSecurityException() {
var mockedField = Mockito.mock(Field.class);
doReturn(this.getClass()).when(mockedField).getType();
var sut = new Reflector<>("", new SpecimenType<>(){});
doThrow(new SecurityException("expected")).when(mockedField).setAccessible(true);
assertThatExceptionOfType(SpecimenException.class)
Expand All @@ -124,6 +171,7 @@ void catchSecurityException() {
@Test
void catchInaccessibleObjectException() {
var mockedField = Mockito.mock(Field.class);
doReturn(this.getClass()).when(mockedField).getType();
var sut = new Reflector<>("", new SpecimenType<>(){});
doThrow(new InaccessibleObjectException("expected")).when(mockedField).setAccessible(true);
assertThatExceptionOfType(SpecimenException.class)
Expand Down