Skip to content

Latest commit

 

History

History
263 lines (188 loc) · 6.52 KB

EXAMPLE.md

File metadata and controls

263 lines (188 loc) · 6.52 KB

Complete Example

This is a complete example where we are validating save and findOne operations

Entity class

  • Entity with all the fields that represent the MyCollection collection.
@Entity
@Value
@Document("MyCollection")
@Builder(toBuilder = true)
public class MyEntity {

    @Id
    @Field(name = "_id")
    String id;
    
    @Field("fooCode")
    int code;
    
    @Field("desc")
    String description;
    
    boolean active;

}

Repository class

  • All allowed operations that are implemented for this database MyMongoDB with the MyCollection collection.
import org.springframework.stereotype.Repository;

@Repository
public class MongoRepository {

    private static  final String MONGO_DATABASE_NAME = "MyMongoDB";
    private final MongoTemplate mongoTemplate;
    
    // We have defined several Databases with their own collections
    public MongoRepository(@Qualifier(MONGO_DATABASE_NAME) final MongoTemplate mongoTemplate) {
        
        this.webappMongoTemplate = mongoTemplate;
    }


    public Optional<MyEntity> findById(final String id) {

        final Query query = new Query();

        query.addCriteria(where("_id").is(id));

        return Optional.ofNullable(this.mongoTemplate.findOne(query, MyEntity.class));
    }

    public MyEntity saveEntity(final MyEntity myEntity) {

        return this.mongoTemplate.save(myEntity);
    }

}

Test class

  • All tests necessary to validate these operations.
Simplified Method ValidationType
validatesEquals EQUALS
validatesNotNull NOT_NULL
validatesNull NULL
validatesCollectionSize COLLECTION_SIZE
validatesJson JSON
validatesJsonByKey JSON_BY_KEY
import io.mongockito.ValidationType;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;

@ExtendWith(MockitoExtension.class)
class MongoRepositoryTest {

    private static final String DEFAULT_KEY_ID = "_id";
    private static final String ID_FIELD = new ObjectId().toHexString();
    
    @Mock(name = "database")
    private MongoTemplate mongoTemplate;
    
    @InjectMocks
    private MongoRepository sut;
    
    @Test
    void should_find_item_by_code_in_my_collection_correctly() {
    
        this.sut.findById( ID_FIELD );
    
        Verify.that()
            .thisOperation( Operation.FIND_ONE )
            .ofClass( MyEntity.class )
            .validatesEquals( DEFAULT_KEY_ID, ID_FIELD )
            .run( this.mongoTemplate );
    
    }

    @Test
    void should_throw_error_on_find_item_by_code_in_my_collection() {
    
        this.sut.findByFooCode( null );
        
        assertThatThrownBy(() -> Verify.that()
            .thisOperation( Operation.FIND_ONE )
            .ofClass( MyEntity.class )
            .validatesNotNull( DEFAULT_KEY_ID )
            .run( this.mongoTemplate ))
        .isInstanceOf(AssertionError.class);
    
    }
    
    @Test
    void should_save_item_in_my_collection_correctly() {
    
        MyEntity myEntity = MyEntity.builder()
            .id( ID_FIELD )
            .fooCode( "bar" )
            .description( "lore ipsum" )
            .active( true )
            .build();
    
        this.sut.save( myEntity );
    
        Verify.that()
            .thisOperation(Operation.SAVE)
            .ofClass( MyEntity.class )
            .validatesJson( myEntity )
            .validatesEquals( "active", true )
            .run( this.mongoTemplate );
    
    }

    @Test
    void should_validate_field_one_by_one_on_save_operation_correctly() {
    
        MyEntity myEntity = MyEntity.builder()
            .id( ID_FIELD )
            .fooCode( "bar" )
            .description( "lore ipsum" )
            .active( true )
            .build();
        
        this.sut.save( myEntity );
        
        Verify.that()
            .thisOperation(Operation.SAVE)
            .ofClass( MyEntity.class )
            .validatesEquals( "fooCode", "bar" )
            .validatesNotNull( "desc" )
            .validatesEquals( "active", true )
            .run( this.mongoTemplate );
    
    }


    @Test
    void should_throw_error_on_save_item_in_my_collection() {
    
        MyEntity myEntity = MyEntity.builder()
            .id( ID_FIELD )
            .fooCode( "bar" )
            .description( "lore ipsum" )
            .active( true )
            .build();
        
        this.sut.save(myEntity);
        
        assertThatThrownBy(() -> Verify.that()
            .thisOperation(Operation.SAVE)
            .ofClass( MyEntity.class )
            .validatesEquals( "active", false )
            .addVerificationMode(times(INTEGER_ONE))
            .run( this.mongoTemplate ))
        .isInstanceOf(AssertionError.class);

    }

}

Creating an adapter method

  • With JSON validation maybe you need to implement your own adapters using 'addAdapter' method
    @Test
    void should_save_item_in_my_collection_correctly() {
    
        MyEntity myEntity = MyEntity.builder()
            .id( ID_FIELD )
            .fooCode( "bar" )
            .description( "lore ipsum" )
            .active( true )
            .build();
    
        this.sut.save( myEntity );
    
        Verify.that()
            .thisOperation(Operation.SAVE)
            .ofClass( MyEntity.class )
            .validatesJson( myEntity )
            .addAdapter(LocalDateTime.class, new LocalDateTimeAdapter())
            .run( this.mongoTemplate );
    
    }
  • LocalDateTimeAdapter definition:
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Objects;

public class LocalDateTimeAdapter extends TypeAdapter<LocalDateTime> {

	// Here, we are defining the iso format for date objects
	private static final DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;

	@Override
	public void write(final JsonWriter out, final LocalDateTime value) throws IOException {

		if (Objects.isNull(value)) {
			out.nullValue();
		} else {
			out.value(formatter.format(value));
		}
	}

	@Override
	public LocalDateTime read(final JsonReader in) throws IOException {

		if (in.peek() == JsonToken.NULL) {
			in.nextNull();
			return null;
		} else {
			final String dateString = in.nextString();
			return LocalDateTime.parse(dateString, formatter);
		}
	}
}