Почему этот код не выполняет одновременный тест на модификациюJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Почему этот код не выполняет одновременный тест на модификацию

Сообщение Anonymous »

Я пытаюсь моделировать (как можно ближе) реальное банковское счет с реальным банковским счетом с методами депозита /снятия. Я попробовал другой подход (AtomicReference , reentrantlock без атомной ссылки), но мой код по -прежнему терпит неудачу в сборе/депозите.

Код: Выделить всё

    public  BigDecimal getBalance() {
try {
reentrantLock.lock();
return balance;
} finally {
reentrantLock.unlock();
}

}

public  void deposit(BigDecimal amount, BigDecimal ceiling) {
try {
reentrantLock.lock();
BigDecimal newBalance = balance.add(amount.abs());
if (newBalance.compareTo(ceiling.abs()) = 0) {
balance = newBalance;
}
} finally {
reentrantLock.unlock();
}

}

Мой класс услуг, который получает значения овердрафта/потолка для учетной записи и депозита вызовов/снятия
public class DepositWithdrawAmount {

private final CeilingPort accountTypePort;

private final OverdraftPort overdraftPort;
private final AccountPort accountPort;

public DepositWithdrawAmount(AccountPort accountPort, CeilingPort accountTypePort, OverdraftPort overdraftPort) {
this.accountPort = accountPort;
this.accountTypePort = accountTypePort;
this.overdraftPort = overdraftPort;
}

public void forAccount(OperationType operationType, UUID accountNumber, BigDecimal amount) throws AccountOperationException {
BankAccount account = accountPort.get(accountNumber);
switch (operationType) {
case WITHDRAW -> {
BigDecimal overdraft = overdraftPort.forAccount(account);
account.withdraw(amount, overdraft);

}
case DEPOSIT -> {
BigDecimal ceiling = accountTypePort.forAccount(account);
account.deposit(amount,ceiling );

}
}
}
}
< /code>
И это мой тестовый класс < /p>
@ExtendWith(MockitoExtension.class)
public class DepositWithdrawConcurrentTest {

@Mock
CeilingPort ceilingPort;
@Mock
AccountPort accountPort;

@Mock
OverdraftPort overdraftPort;
@InjectMocks
DepositWithdrawAmount depositWithdrawAmount1;

@InjectMocks
DepositWithdrawAmount depositWithdrawAmount2;

BankAccount currentAccount;

BigDecimal initialBalance;

private static int numberOfOperations = 100;

@BeforeEach
void beforeEach() {
currentAccount = BankAccount.setupCurrentAccount();
initialBalance = currentAccount.getBalance();
when(accountPort.get(any())).thenReturn(currentAccount);
when(overdraftPort.forAccount(any())).thenReturn(BigDecimal.ZERO);
when(ceilingPort.forAccount(currentAccount)).thenReturn(BigDecimal.valueOf(Integer.MAX_VALUE));
}

@Test
void should_have_same_balance_after_equal_deposit_withdraw_concurrent() throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(10);
List tasks = new ArrayList();
for (int i = 0; i < 50; i++) {
tasks.add(() -> {
depositWithdrawAmount1
.forAccount(OperationType.DEPOSIT, currentAccount.getAccountId(), BigDecimal.valueOf(10));
return null;
});
}

for (int i = 0; i < 50; i++) {
tasks.add(() -> {
depositWithdrawAmount2
.forAccount(OperationType.WITHDRAW, currentAccount.getAccountId(), BigDecimal.valueOf(10));
return null;
});
}

executor.invokeAll(tasks);
executor.shutdown();
executor.awaitTermination(100, TimeUnit.SECONDS);
Assertions.assertEquals(initialBalance,currentAccount.getBalance());

}

}
< /code>
Я использую тест на intellij run run run, пока он не потерпит неудачу, и мой тест всегда не пройдет после примерно 20-30 пробежек.
В моем методе депозита /снятия я пытался использовать AtomisReference и называть сравнение < /code>, но все же тест не проходит.>

Подробнее здесь: https://stackoverflow.com/questions/797 ... ation-test
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»