Home » 2019

Archiv für das Jahr: 2019

Was ist ein Blog

Ein Blog ist eigentlich oft so etwas wie ein Tagebuch. Nur dass ein Blog im Internet geführt wird und (je nach einstellung (normalerweise)) öffentlich ist.

 

Criteria API: Select where in / In list where clause

CriteriaBuilder cb = daoProvider.getEntityManager().getCriteriaBuilder();
CriteriaQuery<Employee2> criteriaQuery = cb.createQuery(Employee2.class);

Root<Employee2> employee2Root = criteriaQuery.from(Employee2.class);
criteriaQuery.select(employee2Root).where(employee2Root.get(Employee2._ATTR_gpn).in(gpns));
TypedQuery<Employee2> query = daoProvider.getEntityManager().createQuery(criteriaQuery);

List<Employee2> employees = query.getResultList();

SSL debuggen

-Djavax.net.debug=ssl

Spring context nach jedem Test löschen / Clean Spring context after each JUnit test

@Dirtiescontext

Cache löschen – at runtime im Debugger

CacheManager.getInstance().clearAll()

Log Level zur Laufzeit im Debugger setzen

((LoggerContext) LoggerFactory.getILoggerFactory()).getLogger("org.springframework.orm.jpa").setLevel(Level.DEBUG);

JVM Heap / MethodArea / Stack

JVM Tuning: Heapsize, Stacksize and Garbage Collection Fundamental

Stack-Size:

What is the default stack size, can it grow, how does it work with garbage collection?

Default Stack Size

Mocks erzeugen für via Class spezifizierte Objekte

Probleme:

Problem 1: Dynamisches Mocking:

Eine Methode soll Mocks für verschiedene Service-Klassen definieren. In der Methode selbst kann nicht jede in ihr zu Mockende Klasse separat auscodiert werden.

D.h.:

Mockito.when(MeineKlasse.meinMethode())

ist nicht möglich.

Stattdessen wird der Methode ein Class -Objekt übergeben, die den zu mockenden Service definiert.

 

Problem 2:
Wenn ein bestimmter request vorliegt muss ein definierter Reply zurück gegeben werden.

MyObj2 mock = Mockito.mock(MyObj2.class);
Mockito.when(mock.returnOnObj(new Bohne1("X"))).thenReturn("desired return");

Problem 3 :
Definition einer Sequenz der durch den Mock zurückzugebender Return-Werte.

MyObj2 mock = Mockito.mock(MyObj2.class);
Mockito.when(mock.returnOnObj(Mockito.any())).thenReturn("1").thenReturn("2").thenReturn("3");

 

Beispiel, das alles obigen Probleme löst:

HPServiceMockFactory.

import org.mockito.stubbing.OngoingStubbing;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.when;

public class HPServiceMockFactory<T> {

    public enum MockMatchingType {IN_SEQUENCE, BY_REQUEST_MATCH};

    public  <T> T prepareMock(T mock, Class bdType, String svcName, MockMatchingType mockMatchingType, Object[] parameters, Object[] desiredReturns){

        Method svc = null;
        for (Method method : bdType.getDeclaredMethods()) {
            // check if method with this name and number of arguments is declared
            if ((method.getParameterTypes().length == parameters.length) && (method.getName().equals(svcName))) {
                // check method parameters
                if (allinstanceof(parameters, method.getParameterTypes())) {
                    try {
                        Object[] paramsForInvocation = new Object[parameters.length];
                        for(int i = 0;  i < parameters.length; i++){
                            if(mockMatchingType.equals(MockMatchingType.IN_SEQUENCE)){
                                // When we want to invoke in sequence: First invocation gets desiredReturn[0], second gets desiredReturn[1], ...
                                // Then we should narrow only to anyObject parameters (or we could narrow the the suiting parameter classes)
                                paramsForInvocation[i] = anyObject();
                            }else{
                                // When we want the mock to return an answer which is defined by its request being equal as the one when the mock is called
                                // then we have to call the mock and pass the expected parameters BEFORE (farther below) define the return values (via the "thenReturn(..))
                                paramsForInvocation[i] = parameters[i];
                            }
                        }

                        svc = bdType.getDeclaredMethod(svcName, method.getParameterTypes());
                        svc.invoke(mock, paramsForInvocation);
                    } catch (NoSuchMethodException e) {
                        throw new IllegalStateException("Failed to initialize mock data, " + e.toString(), e);
                    } catch (InvocationTargetException e) {
                        throw new IllegalStateException("Failed to initialize mock data, " + e.toString(), e);
                    } catch (IllegalAccessException e) {
                        throw new IllegalStateException("Failed to initialize mock data, " + e.toString(), e);
                    }
                }
            }
        }

        if (svc == null) {
            throw new IllegalStateException("Service method could not be found");
        }

        OngoingStubbing<Object> ongoingStubbing = when(svc);
        for(Object desiredReturn : desiredReturns){
            ongoingStubbing = ongoingStubbing.thenReturn(desiredReturn);
        }


        return mock;

    }
    private boolean allinstanceof(Object obj[], Class<?> classes[]) {

        for (int i = 0; i < obj.length; i++) {
            Class<?> clazz = classes[i];
            Object o = obj[i];
            if (clazz.isPrimitive()) {
                if (clazz == boolean.class) {
                    if (!(o instanceof Boolean)) {
                        return false;
                    }
                } else if (clazz == int.class) {
                    if (!(o instanceof Integer)) {
                        return false;
                    }
                }
            } else {
                if (o != null && !clazz.isInstance(o)) {
                    return false;
                }
            }
        }

        return true;
    }
}

Aufrufende Klasse:

import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;

import java.util.Objects;

import static com.ubs.m0m.mock.HPServiceMockFactory.MockMatchingType.BY_REQUEST_MATCH;
import static com.ubs.m0m.mock.HPServiceMockFactory.MockMatchingType.IN_SEQUENCE;

/**
 * Demonstrates how Mockito.when(null) can be used to tell Mockito to
 * return a given value if  objects equals to given ones are passed to the mocked method
 */
public class HPServiceMockTest {
    @Test
    public void mustReturnMockAnswersAsDefinedInASequence(){
        HPService mockedObject = Mockito.mock(HPService.class);
        Object[] parameters = new Object[1];
        parameters[0] = new Bohne1("X");
        String[] desiredReturns = {"Response 1", "Response 2", "Response 3"};
        HPServiceMockFactory myServiceMockFactory = new HPServiceMockFactory<HPService>();
        myServiceMockFactory.prepareMock(mockedObject, HPService.class, "returnOnObj", IN_SEQUENCE,  parameters, desiredReturns);

        Assert.assertEquals(desiredReturns[0], mockedObject.returnOnObj(new Bohne1("ANY")));
        Assert.assertEquals(desiredReturns[1], mockedObject.returnOnObj(new Bohne1("ANY")));
        Assert.assertEquals(desiredReturns[2], mockedObject.returnOnObj(new Bohne1("ANY")));
    }

    @Test
    public void mustReturnMockAnswersThatMatchTheGivenRequest(){
        HPServiceMockFactory myServiceMockFactory = new HPServiceMockFactory<HPService>();
        HPService mockedObject = Mockito.mock(HPService.class);

        Object[] whenReqParams1 = new Object[1];
        whenReqParams1[0] = new Bohne1("Request that must match 1");
        String[] desiredReturns1 = {"Right Response 1"};
        myServiceMockFactory.prepareMock(mockedObject, HPService.class, "returnOnObj", BY_REQUEST_MATCH,  whenReqParams1, desiredReturns1);

        Object[] whenReqParams2 = new Object[1];
        whenReqParams2[0] = new Bohne1("Request that must match 2");
        String[] desiredReturns2 = {"Right Response 2"};
        myServiceMockFactory.prepareMock(mockedObject, HPService.class, "returnOnObj", BY_REQUEST_MATCH,  whenReqParams2, desiredReturns2);

        Assert.assertEquals(desiredReturns1[0], mockedObject.returnOnObj(new Bohne1("Request that must match 1")));
        Assert.assertEquals(desiredReturns2[0], mockedObject.returnOnObj(new Bohne1("Request that must match 2")));
        Assert.assertNull(mockedObject.returnOnObj(new Bohne1("ANY")));
    }

}
class HPService {
    public String returnOnObj(Bohne1 in){return  "not mocked";}
}
class Bohne1 {
    public String id;

    public Bohne1(String id) {
        this.id = id;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Bohne1)) return false;
        Bohne1 bohne1 = (Bohne1) o;
        return Objects.equals(id, bohne1.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}

Dynamische Mocking

Probleme:

Problem 1: Dynamisches Mocking:

Eine Methode soll Mocks für verschiedene Service-Klassen definieren. In der Methode selbst kann nicht jede in ihr zu Mockende Klasse separat auscodiert werden.

D.h.:

Mockito.when(MeineKlasse.meinMethode())

ist nicht möglich.

Stattdessen wird der Methode ein Class -Objekt übergeben, die den zu mockenden Service definiert.

 

Problem 2:
Wenn ein bestimmter request vorliegt muss ein definierter Reply zurück gegeben werden.

MyObj2 mock = Mockito.mock(MyObj2.class);
Mockito.when(mock.returnOnObj(new Bohne1("X"))).thenReturn("desired return");

Problem 3 :
Definition einer Sequenz der durch den Mock zurückzugebender Return-Werte.

MyObj2 mock = Mockito.mock(MyObj2.class);
Mockito.when(mock.returnOnObj(Mockito.any())).thenReturn("1").thenReturn("2").thenReturn("3");

 

Beispiel, das alles obigen Probleme löst:

HPServiceMockFactory.class

import org.mockito.stubbing.OngoingStubbing;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.when;

public class HPServiceMockFactory<T> {

    public enum MockMatchingType {IN_SEQUENCE, BY_REQUEST_MATCH};

    public  <T> T prepareMock(T mock, Class bdType, String svcName, MockMatchingType mockMatchingType, Object[] parameters, Object[] desiredReturns){

        Method svc = null;
        for (Method method : bdType.getDeclaredMethods()) {
            // check if method with this name and number of arguments is declared
            if ((method.getParameterTypes().length == parameters.length) && (method.getName().equals(svcName))) {
                // check method parameters
                if (allinstanceof(parameters, method.getParameterTypes())) {
                    try {
                        Object[] paramsForInvocation = new Object[parameters.length];
                        for(int i = 0;  i < parameters.length; i++){
                            if(mockMatchingType.equals(MockMatchingType.IN_SEQUENCE)){
                                // When we want to invoke in sequence: First invocation gets desiredReturn[0], second gets desiredReturn[1], ...
                                // Then we should narrow only to anyObject parameters (or we could narrow the the suiting parameter classes)
                                paramsForInvocation[i] = anyObject();
                            }else{
                                // When we want the mock to return an answer which is defined by its request being equal as the one when the mock is called
                                // then we have to call the mock and pass the expected parameters BEFORE (farther below) define the return values (via the "thenReturn(..)) 
                                paramsForInvocation[i] = parameters[i];
                            }
                        }

                        svc = bdType.getDeclaredMethod(svcName, method.getParameterTypes());
                        svc.invoke(mock, paramsForInvocation);
                    } catch (NoSuchMethodException e) {
                        throw new IllegalStateException("Failed to initialize mock data, " + e.toString(), e);
                    } catch (InvocationTargetException e) {
                        throw new IllegalStateException("Failed to initialize mock data, " + e.toString(), e);
                    } catch (IllegalAccessException e) {
                        throw new IllegalStateException("Failed to initialize mock data, " + e.toString(), e);
                    }
                }
            }
        }

        if (svc == null) {
            throw new IllegalStateException("Service method could not be found");
        }

        OngoingStubbing<Object> ongoingStubbing = when(svc);
        for(Object desiredReturn : desiredReturns){
            ongoingStubbing = ongoingStubbing.thenReturn(desiredReturn);
        }


        return mock;

    }
    private boolean allinstanceof(Object obj[], Class<?> classes[]) {

        for (int i = 0; i < obj.length; i++) {
            Class<?> clazz = classes[i];
            Object o = obj[i];
            if (clazz.isPrimitive()) {
                if (clazz == boolean.class) {
                    if (!(o instanceof Boolean)) {
                        return false;
                    }
                } else if (clazz == int.class) {
                    if (!(o instanceof Integer)) {
                        return false;
                    }
                }
            } else {
                if (o != null && !clazz.isInstance(o)) {
                    return false;
                }
            }
        }

        return true;
    }
}

Test Klassen:

import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;

import java.util.Objects;

import static com.ubs.m0m.mock.HPServiceMockFactory.MockMatchingType.BY_REQUEST_MATCH;
import static com.ubs.m0m.mock.HPServiceMockFactory.MockMatchingType.IN_SEQUENCE;

/**
 * Demonstrates how Mockito.when(null) can be used to tell Mockito to
 * return a given value if  objects equals to given ones are passed to the mocked method
 */
public class HPServiceMockTest {
    @Test
    public void mustReturnMockAnswersAsDefinedInASequence(){
        HPService mockedObject = Mockito.mock(HPService.class);
        Object[] parameters = new Object[1];
        parameters[0] = new Bohne1("X");
        String[] desiredReturns = {"Response 1", "Response 2", "Response 3"};
        HPServiceMockFactory myServiceMockFactory = new HPServiceMockFactory<HPService>();
        myServiceMockFactory.prepareMock(mockedObject, HPService.class, "returnOnObj", IN_SEQUENCE,  parameters, desiredReturns);

        Assert.assertEquals(desiredReturns[0], mockedObject.returnOnObj(new Bohne1("ANY")));
        Assert.assertEquals(desiredReturns[1], mockedObject.returnOnObj(new Bohne1("ANY")));
        Assert.assertEquals(desiredReturns[2], mockedObject.returnOnObj(new Bohne1("ANY")));
    }

    @Test
    public void mustReturnMockAnswersThatMatchTheGivenRequest(){
        HPServiceMockFactory myServiceMockFactory = new HPServiceMockFactory<HPService>();
        HPService mockedObject = Mockito.mock(HPService.class);

        Object[] whenReqParams1 = new Object[1];
        whenReqParams1[0] = new Bohne1("Request that must match 1");
        String[] desiredReturns1 = {"Right Response 1"};
        myServiceMockFactory.prepareMock(mockedObject, HPService.class, "returnOnObj", BY_REQUEST_MATCH,  whenReqParams1, desiredReturns1);

        Object[] whenReqParams2 = new Object[1];
        whenReqParams2[0] = new Bohne1("Request that must match 2");
        String[] desiredReturns2 = {"Right Response 2"};
        myServiceMockFactory.prepareMock(mockedObject, HPService.class, "returnOnObj", BY_REQUEST_MATCH,  whenReqParams2, desiredReturns2);

        Assert.assertEquals(desiredReturns1[0], mockedObject.returnOnObj(new Bohne1("Request that must match 1")));
        Assert.assertEquals(desiredReturns2[0], mockedObject.returnOnObj(new Bohne1("Request that must match 2")));
        Assert.assertNull(mockedObject.returnOnObj(new Bohne1("ANY")));
    }

}
class HPService {
    public String returnOnObj(Bohne1 in){return  "not mocked";}
}
class Bohne1 {
    public String id;

    public Bohne1(String id) {
        this.id = id;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Bohne1)) return false;
        Bohne1 bohne1 = (Bohne1) o;
        return Objects.equals(id, bohne1.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}
... code ...

Mockito.when(null) – Return basierend auf equality zu gegebenem Input

Mockito.mock(null)

Weshalb sollte das sinn machen?

Mockito.when(null).thenReturn(meinObjekt)

bedeutet eigentlich: Liebes Mockito. Nimm den letzten Aufruf auf irgend einem Mock. Wenn irgendwann derselbe Aufruf mit denselben Parametern gemacht werden sollte, dann gib „meinObjekt“ zurück.

Dies wird unten demonstriert.

import org.mockito.Mockito;

import java.util.Objects;

/**
 * Demonstrates how Mockito.when(null) can be used to tell Mockito to 
 * return a given value if  objects equals to given ones are passed to the mocked method 
 */
public class HPTest {
    public static void main(String[] args) {
        MyObj mockedObject = Mockito.mock(MyObj.class);
        
        /* Tell Mockito, that if get1() is called, then return "super cool string 1.1"*/
        mockedObject.get1();
        Mockito.when(null).thenReturn("super cool string 1.1");
        mockedObject.get2();
        Mockito.when(null).thenReturn("super cool string 2");
        System.out.println(mockedObject.get1());
        System.out.println(mockedObject.get1());
        System.out.println(mockedObject.get2());
        System.out.println(mockedObject.toString());


        /* Tell Mockito, that if return1("1") is called, then return "Return 1" */
        mockedObject.return1("1");
        Mockito.when(null).thenReturn("Return 1");

        /* but if return1("2") is called, then return "Return 2" */
        mockedObject.return1("2");
        Mockito.when(null).thenReturn("Return 2");

        System.out.println(mockedObject.return1("1"));
        System.out.println(mockedObject.return1("2"));
        System.out.println(mockedObject.return1("2"));
        System.out.println(mockedObject.return1("1"));

        mockedObject.returnOnObj(new Bohne("A"));
        Mockito.when(null).thenReturn("On Obj A");

        mockedObject.returnOnObj(new Bohne("B"));
        Mockito.when(null).thenReturn("On Obj B");

        System.out.println(mockedObject.returnOnObj(new Bohne("A")));
        System.out.println(mockedObject.returnOnObj(new Bohne("B")));
        System.out.println(mockedObject.returnOnObj(new Bohne("B")));
        System.out.println(mockedObject.returnOnObj(new Bohne("A")));
    }

}
class MyObj {
    public String get1(){return "not mocked 1";}
    public String get2(){return "not mocked 2";}
    public String return1(String in){return  "not mocked";}
    public String returnOnObj(Bohne in){return  "not mocked";}
}
class Bohne {
    public String id;

    public Bohne(String id) {
        this.id = id;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Bohne)) return false;
        Bohne bohne = (Bohne) o;
        return Objects.equals(id, bohne.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}
/*
Output:
super cool string 1.1
super cool string 1.1
super cool string 2
Mock for MyObj, hashCode: 650023597
Return 1
Return 2
Return 2
Return 1
On Obj A
On Obj B
On Obj B
On Obj A

Process finished with exit code 0
 */