У меня код, который нужно протестировать на потокобезопасность, я хочу сделать это при помощи junit, подскажите как это делается?
Вот код:
public class UserStorage implements Storage {
private final Map<Integer, Account> accounts;
private final Object monitor;
UserStorage() {
this.accounts = new HashMap<>();
this.monitor = new Object();
}
@Override
public boolean addAccount(final Account account) {
synchronized (this.monitor) {
final Account a = this.accounts.get(account.getId());
if (a != null) {
return false;
}
this.accounts.put(account.getId(), account);
return true;
}
}
}
Если тестировать этот метод, не в контексте многопоточности, то получается так:
@Test
public void whenAddNewAccountThenMethodNewAccountReturnTrue() {
Account account = new User(new BigDecimal("1"), "name", 1);
Storage storage = new UserStorage();
boolean result = storage.addAccount(account);
assertTrue(result);
}
@Test
public void whenAddNewAccountButAccountIdIsExistThenMethodAddAccountReturnTrue() {
Account account = new User(new BigDecimal("1"), "name", 1);
Storage storage = new UserStorage();
storage.addAccount(account);
boolean result = storage.addAccount(account);
assertFalse(result);
}
И так далее...
Но, у меня задание в том, что-бы код был потокобезопасный, соответственно, я должен как-то, и протестировать его на это. Помогите пожалуйста, подскажите направление.
Поскольку вызывать ассерты не в потоке junit нельзя, то вы можете запустить тестовые треды через Executors а потом, например, создав барьер дождаться выполнения их всех и проверить уже что получилось.
P.S> Если у вас запись будет редкая, а чтение часто, то не используйте synchronized. Лучше всего StampedLock или если не Java 8, то ReadWriteLock.
Пример:
CompletableFuture future1 = CompletableFuture.runAsync(() -> {
// Выполняем что-то с тестируемым объектом в одном потоке
});
CompletableFuture future2 = CompletableFuture.runAsync(() -> {
//Выполняем что-то с тестируемым объектом в одном потоке
});
СompletableFuture.allOf(future1, future2).thenAccept(v -> {
//Делаем проверки
}).get()
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости