Spock groovy testy

0

Witam, nie moge zrobic prostego testu w spock'u poniewaz metoda zwaca mi nulla. Mecze sie z tym jakies pol dnia, probowalem juz chyba wszystkiego i nie mam pojecia jak to zrobic ... Prosze o pomoc ...

class BankAccountSpec extends Specification {

    @Shared
    private BankAccount account

    @Shared
    private BankAccountFacade bankAccountFacade

    @Shared
    private BankAccountRepository repository

    @Shared
    private BankAccountFactory factory

    def setup() {
        account = new BankAccount()
        repository = Mock(BankAccountRepository)
        factory = Mock(BankAccountFactory)

        bankAccountFacade = new BankAccountConfiguration().bankAccountFacade(
                repository,
                factory
        )
    }

    def '...'() {
        when:
            BankAccount bankAccount = new BankAccount()
        then:
            bankAccount != null
    }
    
    def 'should create bank account with given number'() {
        given:
            account = factory.create('PL91 3018 4529 8669 0250 7367')
        expect:
            account.getNumber() == 'PL91 3018 4529 8669 0250 7367'
    }
}
@Component
@AllArgsConstructor
public class BankAccountFacade {

    private BankAccountRepository repository;
    private BankAccountFactory factory;

    public BankAccount create() {
        return repository.save(factory.create(numberGenerator()));
    }

    private String numberGenerator() {
        Random random = new Random();
        StringBuilder sb = new StringBuilder();
        sb.append("PL");
        do {
            for (int i = 3; i < 30; i++) {
                if (i % 5 == 0) {
                    sb.append(" ");
                } else {
                    int num = random.nextInt(10);
                    sb.append(num);
                }
            }
        } while (isAccountNumberExists(sb.toString()));
        return sb.toString();
    }

    private boolean isAccountNumberExists(String number) {
        return repository.findByNumber(number) != null;
    }

    public BankAccount findById(long id) {
        return repository.findById(id);
    }

    public BankAccount findByNumber(String number) {
        return repository.findByNumber(number);
    }

    public void updateMoney(double money, long senderId, long receiverId) {
        repository.getMoneyFromSender(money, senderId);
        repository.addAmountToReceiver(money, receiverId);
    }

    public Page<BankAccount> findAll(int page, int size) {
        return repository.findAll(new PageRequest(page, size));
    }

    public void modifyBalance(ModifyBalanceDTO dto) {
        repository.modifyBalance(dto.getNewBalance(), dto.getId());
    }
}

@Component
class BankAccountFactory {

    BankAccount create(String generatedNumber) {

        return BankAccount
                .builder()
                .balance(0.0)
                .number(generatedNumber)
                .build();
    }
}

@Configuration
class BankAccountConfiguration {

    @Bean
    BankAccountFacade bankAccountFacade(BankAccountRepository repository,
                                        BankAccountFactory factory) {
        return new BankAccountFacade(repository, factory);
    }
}
@Entity
@Table(name = "bank_accounts")
@NoArgsConstructor
@AllArgsConstructor
@Getter @Setter
@Builder
public class BankAccount {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @NotNull
    @Column(length = 29)
    private String number;

    private double balance;

    @OneToMany(mappedBy = "account", cascade = {CascadeType.MERGE, CascadeType.REMOVE})
    private List<Transaction> transactions = new LinkedList<>();
}

<dependency>
    <groupId>org.spockframework</groupId>
    <artifactId>spock-core</artifactId>
    <version>1.2-groovy-2.5</version>
    <scope>test</scope>
 </dependency>
            	
1

Zapewne chodzi o to, że tworzysz mocka fabryki kont

factory = Mock(BankAccountFactory)

a potem odpalasz na nim create

 given:
            account = factory.create('PL91 3018 4529 8669 0250 7367')
0

Ok, poczytalem troche czym jest Mockowanie ale w dalszym ciagu nie moge osiagnac zamierzonego rezultatu. Gdy dodam oddzielnego @Bean'a do factory to wtedy zadziala to, ale ja chce stworzyc @Bean'a do calosci Fasady, a nie do pojedynczych komponentow.

@Bean
    BankAccountFactory factory() {
        return new BankAccountFactory();
    }

class BankAccountSpec extends Specification {

    @Shared
    private BankAccount account

    @Shared
    private BankAccountFacade bankAccountFacade

    @Shared
    private BankAccountRepository repository

    @Shared
    private BankAccountFactory factory

    def setupSpec() {
        account = new BankAccount()
        factory = new BankAccountConfiguration().factory()
        //repository = Mock(BankAccountRepository)

//        bankAccountFacade = new BankAccountConfiguration().bankAccountFacade(
//                repository,
//                factory
//        )
    }

    def 'should create bank account with given number'() {
        given:
            account = factory.create('PL91 3018 4529 8669 0250 7367')
        expect:
            account.number == 'PL91 3018 4529 8669 0250 7367'
    }
}

0

Nie rozumiem co chcesz zrobić, ale po prostu wywal te mocki. Nie są Ci potrzebne raczej. (W zdrowym kodzie są nieczęsto potrzebne).

0
class BankAccountSpec extends Specification {

    @Shared
    private BankAccount account

    @Shared
    private BankAccountFacade bankAccountFacade

    @Shared
    private BankAccountRepository repository

    @Shared
    private BankAccountFactory factory

    def setupSpec() {
        account = new BankAccount()

        bankAccountFacade = new BankAccountConfiguration().bankAccountFacade(
                repository,
                factory
        )
    }

    def 'should create bank account with given number'() {
        given:
            account = bankAccountFacade.create()
        expect:
            account != null
    }
}

@Configuration
class BankAccountConfiguration {

    @Bean
    BankAccountFacade bankAccountFacade(BankAccountRepository repository,
                                        BankAccountFactory factory) {
        return new BankAccountFacade(repository, factory);
    }
}
@Component
@AllArgsConstructor
public class BankAccountFacade {

    private BankAccountRepository repository;
    private BankAccountFactory factory;

    public BankAccount create() {
        return repository.save(factory.create(numberGenerator()));
    }

    private String numberGenerator() {
        Random random = new Random();
        StringBuilder sb = new StringBuilder();
        sb.append("PL");
        do {
            for (int i = 3; i < 30; i++) {
                if (i % 5 == 0) {
                    sb.append(" ");
                } else {
                    int num = random.nextInt(10);
                    sb.append(num);
                }
            }
        } while (isAccountNumberExists(sb.toString()));
        return sb.toString();
    }

    private boolean isAccountNumberExists(String number) {
        return repository.findByNumber(number) != null;
    }
}
interface BankAccountRepository extends JpaRepository<BankAccount, Long> {}
@Component
class BankAccountFactory {

    BankAccount create(String generatedNumber) {

        return BankAccount
                .builder()
                .balance(0.0)
                .number(generatedNumber)
                .build();
    }
}

Logi z testu

java.lang.NullPointerException
	at pl.robert.project.bank_account.BankAccountFacade.isAccountNumberExists(BankAccountFacade.java:40)
	at pl.robert.project.bank_account.BankAccountFacade.numberGenerator(BankAccountFacade.java:35)
	at pl.robert.project.bank_account.BankAccountFacade.create(BankAccountFacade.java:19)
	at pl.robert.project.bank_account.BankAccountSpec.should create bank account with given number(BankAccountSpec.groovy:32)


Process finished with exit code 255

1 użytkowników online, w tym zalogowanych: 0, gości: 1