Merge branch 'master' of https://github.com/eugenp/tutorials into future-vavr
This commit is contained in:
commit
31a0f7b817
|
@ -83,6 +83,24 @@
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openjdk.jmh</groupId>
|
||||||
|
<artifactId>jmh-core</artifactId>
|
||||||
|
<version>1.19</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openjdk.jmh</groupId>
|
||||||
|
<artifactId>jmh-generator-annprocess</artifactId>
|
||||||
|
<version>1.19</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openjdk.jmh</groupId>
|
||||||
|
<artifactId>jmh-generator-bytecode</artifactId>
|
||||||
|
<version>1.19</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
package com.baeldung.counter;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.openjdk.jmh.annotations.Benchmark;
|
||||||
|
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||||
|
import org.openjdk.jmh.annotations.Fork;
|
||||||
|
import org.openjdk.jmh.annotations.Mode;
|
||||||
|
|
||||||
|
import com.baeldung.counter.CounterUtil.MutableInteger;
|
||||||
|
|
||||||
|
@Fork(value = 1, warmups = 3)
|
||||||
|
@BenchmarkMode(Mode.All)
|
||||||
|
public class CounterStatistics {
|
||||||
|
|
||||||
|
private static final Map<String, Integer> counterMap = new HashMap<>();
|
||||||
|
private static final Map<String, MutableInteger> counterWithMutableIntMap = new HashMap<>();
|
||||||
|
private static final Map<String, int[]> counterWithIntArrayMap = new HashMap<>();
|
||||||
|
private static final Map<String, Long> counterWithLongWrapperMap = new HashMap<>();
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void wrapperAsCounter() {
|
||||||
|
CounterUtil.counterWithWrapperObject(counterMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void lambdaExpressionWithWrapper() {
|
||||||
|
CounterUtil.counterWithLambdaAndWrapper(counterWithLongWrapperMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void mutableIntegerAsCounter() {
|
||||||
|
CounterUtil.counterWithMutableInteger(counterWithMutableIntMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void primitiveArrayAsCounter() {
|
||||||
|
CounterUtil.counterWithPrimitiveArray(counterWithIntArrayMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
org.openjdk.jmh.Main.main(args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.baeldung.counter;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.baeldung.counter.CounterUtil.MutableInteger;
|
||||||
|
|
||||||
|
public class CounterTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenMapWithWrapperAsCounter_runsSuccessfully() {
|
||||||
|
Map<String, Integer> counterMap = new HashMap<>();
|
||||||
|
CounterUtil.counterWithWrapperObject(counterMap);
|
||||||
|
|
||||||
|
assertEquals(3, counterMap.get("China")
|
||||||
|
.intValue());
|
||||||
|
assertEquals(2, counterMap.get("India")
|
||||||
|
.intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenMapWithLambdaAndWrapperCounter_runsSuccessfully() {
|
||||||
|
Map<String, Long> counterMap = new HashMap<>();
|
||||||
|
CounterUtil.counterWithLambdaAndWrapper(counterMap);
|
||||||
|
|
||||||
|
assertEquals(3l, counterMap.get("China")
|
||||||
|
.longValue());
|
||||||
|
assertEquals(2l, counterMap.get("India")
|
||||||
|
.longValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenMapWithMutableIntegerCounter_runsSuccessfully() {
|
||||||
|
Map<String, MutableInteger> counterMap = new HashMap<>();
|
||||||
|
CounterUtil.counterWithMutableInteger(counterMap);
|
||||||
|
assertEquals(3, counterMap.get("China")
|
||||||
|
.getCount());
|
||||||
|
assertEquals(2, counterMap.get("India")
|
||||||
|
.getCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenMapWithPrimitiveArray_runsSuccessfully() {
|
||||||
|
Map<String, int[]> counterMap = new HashMap<>();
|
||||||
|
CounterUtil.counterWithPrimitiveArray(counterMap);
|
||||||
|
assertEquals(3, counterMap.get("China")[0]);
|
||||||
|
assertEquals(2, counterMap.get("India")[0]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
package com.baeldung.counter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class CounterUtil {
|
||||||
|
|
||||||
|
private final static String[] COUNTRY_NAMES = { "China", "Australia", "India", "USA", "USSR", "UK", "China", "France", "Poland", "Austria", "India", "USA", "Egypt", "China" };
|
||||||
|
|
||||||
|
public static void counterWithWrapperObject(Map<String, Integer> counterMap) {
|
||||||
|
for (String country : COUNTRY_NAMES) {
|
||||||
|
counterMap.compute(country, (k, v) -> v == null ? 1 : v + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void counterWithLambdaAndWrapper(Map<String, Long> counterMap) {
|
||||||
|
counterMap.putAll(Stream.of(COUNTRY_NAMES)
|
||||||
|
.parallel()
|
||||||
|
.collect(Collectors.groupingBy(k -> k, Collectors.counting())));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class MutableInteger {
|
||||||
|
int count;
|
||||||
|
|
||||||
|
public MutableInteger(int count) {
|
||||||
|
this.count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void increment() {
|
||||||
|
this.count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCount() {
|
||||||
|
return this.count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void counterWithMutableInteger(Map<String, MutableInteger> counterMap) {
|
||||||
|
for (String country : COUNTRY_NAMES) {
|
||||||
|
MutableInteger oldValue = counterMap.get(country);
|
||||||
|
if (oldValue != null) {
|
||||||
|
oldValue.increment();
|
||||||
|
} else {
|
||||||
|
counterMap.put(country, new MutableInteger(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void counterWithPrimitiveArray(Map<String, int[]> counterMap) {
|
||||||
|
for (String country : COUNTRY_NAMES) {
|
||||||
|
int[] oldCounter = counterMap.get(country);
|
||||||
|
if (oldCounter != null) {
|
||||||
|
oldCounter[0] += 1;
|
||||||
|
} else {
|
||||||
|
counterMap.put(country, new int[] { 1 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package com.baeldung.kotlin
|
||||||
|
|
||||||
|
import org.junit.Assert
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class ExtensionMethods {
|
||||||
|
@Test
|
||||||
|
fun simpleExtensionMethod() {
|
||||||
|
fun String.escapeForXml() : String {
|
||||||
|
return this
|
||||||
|
.replace("&", "&")
|
||||||
|
.replace("<", "<")
|
||||||
|
.replace(">", ">")
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.assertEquals("Nothing", "Nothing".escapeForXml())
|
||||||
|
Assert.assertEquals("<Tag>", "<Tag>".escapeForXml())
|
||||||
|
Assert.assertEquals("a&b", "a&b".escapeForXml())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun genericExtensionMethod() {
|
||||||
|
fun <T> T.concatAsString(b: T) : String {
|
||||||
|
return this.toString() + b.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.assertEquals("12", "1".concatAsString("2"))
|
||||||
|
Assert.assertEquals("12", 1.concatAsString(2))
|
||||||
|
// This doesn't compile
|
||||||
|
// Assert.assertEquals("12", 1.concatAsString(2.0))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun infixExtensionMethod() {
|
||||||
|
infix fun Number.toPowerOf(exponent: Number): Double {
|
||||||
|
return Math.pow(this.toDouble(), exponent.toDouble())
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.assertEquals(9.0, 3 toPowerOf 2, 0.1)
|
||||||
|
Assert.assertEquals(3.0, 9 toPowerOf 0.5, 0.1)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun operatorExtensionMethod() {
|
||||||
|
operator fun List<Int>.times(by: Int): List<Int> {
|
||||||
|
return this.map { it * by }
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.assertEquals(listOf(2, 4, 6), listOf(1, 2, 3) * 2)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
package org.baeldung.bddmockito;
|
||||||
|
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
import static org.mockito.BDDMockito.*;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.invocation.InvocationOnMock;
|
||||||
|
|
||||||
|
|
||||||
|
public class BDDMockitoTest {
|
||||||
|
|
||||||
|
PhoneBookService phoneBookService;
|
||||||
|
PhoneBookRepository phoneBookRepository;
|
||||||
|
|
||||||
|
String momContactName = "Mom";
|
||||||
|
String momPhoneNumber = "01234";
|
||||||
|
String xContactName = "x";
|
||||||
|
String tooLongPhoneNumber = "01111111111111";
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() {
|
||||||
|
phoneBookRepository = Mockito.mock(PhoneBookRepository.class);
|
||||||
|
phoneBookService = new PhoneBookService(phoneBookRepository);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenValidContactName_whenSearchInPhoneBook_thenRetunPhoneNumber() {
|
||||||
|
given(phoneBookRepository.contains(momContactName)).willReturn(true);
|
||||||
|
given(phoneBookRepository.getPhoneNumberByContactName(momContactName))
|
||||||
|
.will((InvocationOnMock invocation) -> {
|
||||||
|
if(invocation.getArgument(0).equals(momContactName)) {
|
||||||
|
return momPhoneNumber;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
String phoneNumber = phoneBookService.search(momContactName);
|
||||||
|
|
||||||
|
then(phoneBookRepository).should().contains(momContactName);
|
||||||
|
then(phoneBookRepository).should().getPhoneNumberByContactName(momContactName);
|
||||||
|
Assert.assertEquals(phoneNumber, momPhoneNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenInvalidContactName_whenSearch_thenRetunNull() {
|
||||||
|
given(phoneBookRepository.contains(xContactName)).willReturn(false);
|
||||||
|
|
||||||
|
String phoneNumber = phoneBookService.search(xContactName);
|
||||||
|
|
||||||
|
then(phoneBookRepository).should().contains(xContactName);
|
||||||
|
then(phoneBookRepository).should(never()).getPhoneNumberByContactName(xContactName);
|
||||||
|
Assert.assertEquals(phoneNumber, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenValidContactNameAndPhoneNumber_whenRegister_thenSucceed() {
|
||||||
|
given(phoneBookRepository.contains(momContactName)).willReturn(false);
|
||||||
|
|
||||||
|
phoneBookService.register(momContactName, momPhoneNumber);
|
||||||
|
|
||||||
|
verify(phoneBookRepository).insert(momContactName, momPhoneNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenEmptyPhoneNumber_whenRegister_thenFail() {
|
||||||
|
given(phoneBookRepository.contains(momContactName)).willReturn(false);
|
||||||
|
|
||||||
|
phoneBookService.register(xContactName, "");
|
||||||
|
|
||||||
|
then(phoneBookRepository).should(never()).insert(momContactName, momPhoneNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenLongPhoneNumber_whenRegister_thenFail() {
|
||||||
|
given(phoneBookRepository.contains(xContactName)).willReturn(false);
|
||||||
|
willThrow(new RuntimeException())
|
||||||
|
.given(phoneBookRepository).insert(any(String.class), eq(tooLongPhoneNumber));
|
||||||
|
|
||||||
|
try {
|
||||||
|
phoneBookService.register(xContactName, tooLongPhoneNumber);
|
||||||
|
fail("Should throw exception");
|
||||||
|
} catch (RuntimeException ex) { }
|
||||||
|
|
||||||
|
then(phoneBookRepository).should(never()).insert(momContactName, tooLongPhoneNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenExistentContactName_whenRegister_thenFail() {
|
||||||
|
given(phoneBookRepository.contains(momContactName))
|
||||||
|
.willThrow(new RuntimeException("Name already exist"));
|
||||||
|
|
||||||
|
try {
|
||||||
|
phoneBookService.register(momContactName, momPhoneNumber);
|
||||||
|
fail("Should throw exception");
|
||||||
|
} catch(Exception ex) { }
|
||||||
|
|
||||||
|
then(phoneBookRepository).should(never()).insert(momContactName, momPhoneNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package org.baeldung.bddmockito;
|
||||||
|
|
||||||
|
public interface PhoneBookRepository {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert phone record
|
||||||
|
* @param name Contact name
|
||||||
|
* @param phone Phone number
|
||||||
|
*/
|
||||||
|
void insert(String name, String phone);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search for contact phone number
|
||||||
|
* @param name Contact name
|
||||||
|
* @return phone number
|
||||||
|
*/
|
||||||
|
String getPhoneNumberByContactName(String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the phonebook contains this contact
|
||||||
|
* @param name Contact name
|
||||||
|
* @return true if this contact name exists
|
||||||
|
*/
|
||||||
|
boolean contains(String name);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package org.baeldung.bddmockito;
|
||||||
|
|
||||||
|
public class PhoneBookService {
|
||||||
|
|
||||||
|
private PhoneBookRepository phoneBookRepository;
|
||||||
|
|
||||||
|
public PhoneBookService(PhoneBookRepository phoneBookRepository) {
|
||||||
|
this.phoneBookRepository = phoneBookRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a contact
|
||||||
|
* @param name Contact name
|
||||||
|
* @param phone Phone number
|
||||||
|
*/
|
||||||
|
public void register(String name, String phone) {
|
||||||
|
if(!name.isEmpty() && !phone.isEmpty() && !phoneBookRepository.contains(name)) {
|
||||||
|
phoneBookRepository.insert(name, phone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search for a phone number by contact name
|
||||||
|
* @param name Contact name
|
||||||
|
* @return Phone number
|
||||||
|
*/
|
||||||
|
public String search(String name) {
|
||||||
|
if(!name.isEmpty() && phoneBookRepository.contains(name)) {
|
||||||
|
return phoneBookRepository.getPhoneNumberByContactName(name);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue