Skip to content
Advertisement

Setter in DTO just for integration testing?

I couldn’t find the info I’m looking for hence posting here for suggestion and getting to know better approach.

I have an immutable DTO object like:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.time.LocalDate;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class AccountCreateDto {
    String name;
    Long accountNo;
    String email;
    LocalDate dob;
    String address;
    Long phone;
    Integer amount;
    LocalDate accountOpeningDate;
    Integer installmentAmount;
    Integer totalAmount;
    LocalDate installmentPaidDate;

    @JsonCreator
    public AccountCreateDto(
            @JsonProperty("name") String name,
            @JsonProperty("accountNo") Long accountNo,
            @JsonProperty("email") String email,
            @JsonProperty("dob") LocalDate dob,
            @JsonProperty("address") String address,
            @JsonProperty("phone") Long phone,
            @JsonProperty("amount") Integer amount,
            @JsonProperty("accountOpeningDate") LocalDate accountOpeningDate,
            @JsonProperty("installmentAmount") Integer installmentAmount,
            @JsonProperty("totalAmount") Integer totalAmount,
            @JsonProperty("installmentPaidDate") LocalDate installmentPaidDate
    ) {
        this.name = name;
        this.accountNo = accountNo;
        this.email = email;
        this.dob = dob;
        this.address = address;
        this.phone = phone;
        this.amount = amount;
        this.accountOpeningDate = accountOpeningDate;
        this.installmentAmount = installmentAmount;
        this.totalAmount = totalAmount;
        this.installmentPaidDate = installmentPaidDate;
    }
    // removing getters for brevity
}

Now I’m working on an integration test with testcontainer where I want the accountOpeningDate and installmentPaidDate to be dynamic value hence in order to set these values from Integration Tests, is it a good idea to add only 2 setters to this DTO which is only to be used for Integration Tests like below?

    public void setAccountOpeningDate(LocalDate accountOpeningDate) {
        this.accountOpeningDate = accountOpeningDate;
    }

    public void setInstallmentPaidDate(LocalDate installmentPaidDate) {
        this.installmentPaidDate = installmentPaidDate;
    }

Or is there a better approach than this? Looking for recommendations.

TA

Advertisement

Answer

It is not acceptable you will lose the immutability of the object. With immutable classes, we can’t modify the state but must create a new instance with the mutated state.
The builder pattern is very useful in this case.
Example:

AccountCreateDto existingImmutableDTO = new AccountCreateDto("name", 1L, "name@aaa", LocalDate.now(), "Address", null, null, null, null, null, null );
        
//change state of imuttable object, create new instance via builder
AccountCreateDto modifiedImmutableDTO = new AccountCreateDtoBuilder(existingImmutableDTO).setAccountOpeningDate(LocalDate.now()).setInstallmentPaidDate(LocalDate.now()).build();
public class AccountCreateDtoBuilder {
    private String name;
    private Long accountNo;
    private String email;
    private LocalDate dob;
    private String address;
    private Long phone;
    private Integer amount;
    private LocalDate accountOpeningDate;
    private Integer installmentAmount;
    private Integer totalAmount;
    private LocalDate installmentPaidDate;

    public AccountCreateDtoBuilder() {
        
    }

    public AccountCreateDtoBuilder(AccountCreateDto accountCreateDto) {
        this.name = accountCreateDto.getName();
        this.accountNo = accountCreateDto.getAccountNo();
        this.email = accountCreateDto.getEmail();
        this.dob = accountCreateDto.getDob();
        this.address = accountCreateDto.getAddress();
        this.phone = accountCreateDto.getPhone();
        this.amount = accountCreateDto.getAmount();
        this.accountOpeningDate = accountCreateDto.getAccountOpeningDate();
        this.installmentAmount = accountCreateDto.getInstallmentAmount();
        this.totalAmount = accountCreateDto.getTotalAmount();
        this.installmentPaidDate = accountCreateDto.getInstallmentPaidDate();
    }

    public AccountCreateDto build() {
        return new AccountCreateDto(name, accountNo, email, dob, address, phone, amount, accountOpeningDate, installmentAmount, totalAmount, installmentPaidDate);
    }

    public AccountCreateDtoBuilder setName(String name) {
        this.name = name;
        return this;
    }

    public AccountCreateDtoBuilder setAccountNo(Long accountNo) {
        this.accountNo = accountNo;
        return this;
    }

    public AccountCreateDtoBuilder setEmail(String email) {
        this.email = email;
        return this;
    }

    public AccountCreateDtoBuilder setDob(LocalDate dob) {
        this.dob = dob;
        return this;
    }

    public AccountCreateDtoBuilder setAddress(String address) {
        this.address = address;
        return this;
    }

    public AccountCreateDtoBuilder setPhone(Long phone) {
        this.phone = phone;
        return this;
    }

    public AccountCreateDtoBuilder setAmount(Integer amount) {
        this.amount = amount;
        return this;
    }

    public AccountCreateDtoBuilder setAccountOpeningDate(LocalDate accountOpeningDate) {
        this.accountOpeningDate = accountOpeningDate;
        return this;
    }

    public AccountCreateDtoBuilder setInstallmentAmount(Integer installmentAmount) {
        this.installmentAmount = installmentAmount;
        return this;
    }

    public AccountCreateDtoBuilder setTotalAmount(Integer totalAmount) {
        this.totalAmount = totalAmount;
        return this;
    }

    public AccountCreateDtoBuilder setInstallmentPaidDate(LocalDate installmentPaidDate) {
        this.installmentPaidDate = installmentPaidDate;
        return this;
    }
}

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement