Spock groovy testy

Spock groovy testy
AP
  • Rejestracja:około 6 lat
  • Ostatnio:około 6 lat
  • Postów:5
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 ...

Kopiuj
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'
    }
}
Kopiuj
@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());
    }
}

Kopiuj
@Component
class BankAccountFactory {

    BankAccount create(String generatedNumber) {

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

Kopiuj
@Configuration
class BankAccountConfiguration {

    @Bean
    BankAccountFacade bankAccountFacade(BankAccountRepository repository,
                                        BankAccountFactory factory) {
        return new BankAccountFacade(repository, factory);
    }
}
Kopiuj
@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<>();
}

Kopiuj
<dependency>
    <groupId>org.spockframework</groupId>
    <artifactId>spock-core</artifactId>
    <version>1.2-groovy-2.5</version>
    <scope>test</scope>
 </dependency>
            	
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:minuta
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4709
1

Zapewne chodzi o to, że tworzysz mocka fabryki kont

Kopiuj
factory = Mock(BankAccountFactory)

a potem odpalasz na nim create

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

jeden i pół terabajta powinno wystarczyć każdemu
AP
  • Rejestracja:około 6 lat
  • Ostatnio:około 6 lat
  • Postów:5
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.

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

Kopiuj
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'
    }
}

jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:minuta
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4709
0

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


jeden i pół terabajta powinno wystarczyć każdemu
AP
Chodzi o to ze mam config napisany. W configu zwracam fasade z repository i factory. Tylko wtedy jak w groovym odwolam sie do tego to factory jest nullem. Ale jak zrobie @Bean'a do factory oddzielnie to wtedy dziala. Nie da sie tego zrobic za pomoca tego @Bean'a fasady co mam? O to mi chodzi
AP
Tak samo nie moge wywolac repository bo jest nullem
jarekr000000
Dlaczego miałby nie być nullem? Gdzie go tworzysz? Wywal mocki i rób obiekty przez new jak cżłowiek. Nie będzie nulli.
AP
  • Rejestracja:około 6 lat
  • Ostatnio:około 6 lat
  • Postów:5
0
Kopiuj
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
    }
}

Kopiuj
@Configuration
class BankAccountConfiguration {

    @Bean
    BankAccountFacade bankAccountFacade(BankAccountRepository repository,
                                        BankAccountFactory factory) {
        return new BankAccountFacade(repository, factory);
    }
}
Kopiuj
@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;
    }
}
Kopiuj
interface BankAccountRepository extends JpaRepository<BankAccount, Long> {}
Kopiuj
@Component
class BankAccountFactory {

    BankAccount create(String generatedNumber) {

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

Logi z testu

Kopiuj
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

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.