2011-07-13 13 views
5

piszę jednostki badań dla mojej aplikacji grails, i zdałem sobie sprawę, nie wiem właściwą drogę do dochodzenia, czy obiekt jest właściwym przedmiotem lub nie.właściwy sposób porównać obiektu w badanej jednostki

Na przykład, biorąc pod uwagę ten test:

void testExampleTest() { 
    mockSession.person = new Person(firstName:'John', lastName:'Doe', middleInitial:'E') 
    def model = controller.testMethod() 
    ...assertions... 
} 

i

def testMethod = { 
    Person currPerson = session.getAttribute("person") 
    render(view:'view',model:[person:currPerson] 
} 

jaki sposób należy upewnić się, że obiekt osoba dodałem do sesji jest właściwie były przekazywane w modelu? Czy to wystarczy użyć

assertEquals(person,model['person']) 

lub dlatego, że wstrzyknięty obiektowi się do sesji to więcej sensu używać

assertEquals(person.firstName, model['person'].firstName) 
assertEquals(person.lastName, model['person'].lastName) 
assertequals(person.middleName, model['person'].middleName) 

Wydaje mi się, że pierwszy sposób powinno wystarczyć, o ile obiekt ma poprawnie zdefiniowaną metodę równości, ale chciałem tylko zobaczyć, jaki jest konwencjonalny sposób.

Dzięki

Odpowiedz

2

Porównanie właściwości według właściwości musi być powtarzane w każdym teście - więc jest to dobre stare powielanie kodu, a test smell described in XUnitPatterns. Lepiej mieć odpowiednie equals().

Oczywiście można dodać metodę użytkową personEquals() lub nawet zastąpić Person.equals() w środowisku wykonawczym. W przypadku wyśmiewanej klasy prawdopodobnie będziesz musiał. Osobiście trzymam się krótszego kodu, który jest jednym z assertEquals(), kiedy to możliwe.

2

Zabawne, ja i kolega mieliśmy dzisiaj podobną dyskusję. Nasz wniosek był taki, że

Zaletą bardziej pracochłonnego porównywania atrybutów z atrybutami jest to, że raportuje określoną różnicę, a nie tylko "nie, nie są one równe", a to może być wygodne.

Również nie mamy kontroli nad niektórych klas, a niektóre z nich brakowało równy sposób.

Zamierzamy zbadać, czy to możliwe, aby użyć refleksji do wdrożenia komparator, stąd usunięcie niektórych z nudy.

+0

Zobacz także moją odpowiedź: Biblioteka commons-beans upraszcza korzystanie z dostępu opartego na odbiciu, który może być wykorzystany do tworzenia metod wielokrotnych własności. –

1

Jeśli równe jest zdefiniowane poprawnie, masz rację. Problem polega na tym, że być może trzeba najpierw wykonać test jednostkowy, jeśli równe jest zdefiniowane poprawnie (co oznacza, że ​​zachowuje się tak, jak tego oczekujesz).

Może to trochę trudniejsze, jeśli stworzyć makietę dla klasy Person. W takim przypadku nie obchodzi cię, czy equals działa poprawnie, ponieważ chcesz tylko sprawdzić, czy niektóre atrybuty są ustawiane/dostępne poprawnie. Dlatego wolę sprawdzać prymitywne wartości, jeśli to możliwe i konieczne. Uważam, że sprawia to, że testy są również bardziej opisowe (chociaż może stać się dość gadatliwa).

0

Jak pisałeś, jeśli dane testowe mają właściwą metodę równości, możesz z niej skorzystać. "Właściwa" oznacza, że ​​testuje atrybuty, które chcesz przetestować.

Często pracuję z jednostkami baz danych, które tylko porównują ich atrybut identyfikatora. W przypadku tych obiektów muszę przetestować każdy atrybut osobno, aby sprawdzić, czy są one równe. Pisałem trochę pomocnika, który pozwala mi pisać pojedynczy dochodzić do wielu właściwości, na przykład:

assertEqualProperties(person, model['person'], "firstName", "lastName", "middleName"); 

Ta metoda pomocnika używa refleksji dostępu do atrybutów (nie bezpośrednio, modlę bibliotekę Commons fasola). W Groovy z pewnością jest składnia, która nie wymaga jednoznacznej refleksji. Metoda zgłasza pierwszy nie-równy atrybut jako błąd testu.

0

w Grails każdy obiekt jest możliwy do serializacji, więc można porównać dwa używając ich Serializations XML:

public void compareXML(Object a, Object b) 
    ByteArrayOutputStream aBaos = new ByteArrayOutputStream(); 
    XMLEncoder aEncoder = new XMLEncoder(aBaos); 
    aEncoder.writeObject(a); 
    aEncoder.close(); 
    String xmlA = baos.toString(); 

    ByteArrayOutputStream bBaos = new ByteArrayOutputStream(); 
    XMLEncoder bEncoder = new XMLEncoder(bBaos); 
    bEncoder.writeObject(b); 
    bEncoder.close(); 
    String xmlB = bBaos.toString(); 

    assertEquals(xmlA, xmlB); 
} 

Jeśli pracujesz w Eclipse, dostaniesz wielki tekstowy porównania dwóch ciągów XML pokazano wszystkie różnice.

+0

GUNIT Grailsa wykonuje lepszą pracę przy tekstowej reprezentacji różnic między obiektami. –

1

W tym konkretnym przypadku testowanie poszczególnych właściwości jest tylko sposobem identyfikacji konkretnej instancji obiektu i zamazuje znaczenie testu. Czego konkretnie obchodzi i powinien twierdzić, że model['person'] jest dokładnie taki sam przedmiot jak to, co początkowo umieścić w jak person:

assertSame(person, model['person']) 

Albo z Hamcrest, co pozwala znacznie bardziej wyraziste twierdzenia ogólne:

assertThat(model['person'], sameInstance(person)) 
+0

Rzeczywiście, jeśli oczekuje się, że obiekt poddany testowi przyniesie to samo wystąpienie, należy dokładnie to sprawdzić. –

0

Używam assertSame(). Porównanie pola za polem jest o wiele bardziej pracochłonne, niż to konieczne - szydziłeś z danych, więc po prostu potwierdzaj, że wyśmiewane wartości są poprawnie zwracane.

2

I odkryli, że robi własność majątek jest trochę bardziej niezawodny i daje trochę bardziej precyzyjną kontrolę ziarna nad tym, jak coś jest porównywana, wadą jest to trochę więcej pracy, aby skonfigurować i utrzymać

Powiązane problemy