2015-02-11 21 views
6

Wyobraźmy sobie, mam następujące klasy:Co to jest analogon Mockito.spy/doReturn w EasyMock?

public class TestClass { 
    public class Index<X> { 

    } 
    public class IndexData { 
     private final Index<?> index; 

     private final ReentrantReadWriteLock lock = 
      new ReentrantReadWriteLock(); 

     public IndexData(final Index<?> index) { 
      super(); 
      this.index = index; 
     } 

     public Index<?> getIndex() { 
      return index; 
     } 

     public Lock getReadLock() { 
      return lock.readLock(); 
     } 

     public Lock getWriteLock() { 
      return lock.writeLock(); 
     } 
    } 

    public void add(final InputClass input) 
    { 
     final IndexData index = getIndex(input); 

     final Lock lock = index.getWriteLock(); 
     lock.lock(); 
     try { 
      // Do something here, which requires synchronization 
     } finally { 
      lock.unlock(); 
     } 
    } 

    protected IndexData getIndex(final InputClass input) { 
     // Some logic of getting the index for input 
     return null; 
    } 
} 

Chcę napisać badanej jednostki, która sprawdza,

  1. w metodzie add, index.getWriteLock() jest używany (nie index.getReadLock())
  2. z blokada została zwolniona i zwolniono
  3. .

Korzystanie Mockito mogę napisać test takiego:

@Test 
public void testAddUsesWriteLock() { 
    // Prepare 
    final TestClass objectUnderTest = Mockito.spy(new TestClass()); 
    final InputClass input = Mockito.mock(InputClass.class); 
    final IndexData indexData = Mockito.mock(IndexData.class); 
    Mockito.doReturn(indexData).when(objectUnderTest).getIndex(input); 
    final Lock lock = Mockito.mock(Lock.class); 
    Mockito.doReturn(lock).when(indexData).getWriteLock(); 

    // Invoke method under test 
    objectUnderTest.add(input); 

    // Verify 
    Mockito.verify(indexData).getWriteLock(); 
    Mockito.verify(indexData, Mockito.never()).getReadLock(); 
    Mockito.verify(lock).lock(); 
    Mockito.verify(lock).unlock(); 
} 

Jak mogę zrobić to samo z EasyMock?

Beton: Jak mogę zwrócić metodę w EasyMock (linia Mockito.doReturn(indexData).when(objectUnderTest).getIndex(input)) w trybie getIndex?

Uwaga: Kod ten można znaleźć pod następującym numerem: here.

+0

Przepraszam, jeśli tylko Dokładna odpowiedź dotycząca Easymocka, ale myślę, że musisz zrobić krok wstecz i zadać sobie pytanie, dlaczego musisz "szpiegować" ("spy()" klasę, którą próbujesz przetestować. Jest to ogólnie [uznawane za zapach kodu] (http: //programmers.stackexchange.com/questions/212493/is-spying-on-test-class-bad-practice). Pomyślałem, że warto o tym wspomnieć na wypadek, gdybyście byli nowi w pisaniu testów tego rodzaju i mieli możliwość refaktoryzacji kodu. – Brad

+0

@Brad Wiem, że tę praktykę można uznać za zły projekt. Jednak dla mnie ważniejsze jest przetestowanie wszystkiego, co chcę, niż eleganckiego projektu. Zasadniczo chcę mieć możliwość napisania automatycznego testu dla większości błędów wykrywanych ręcznie. W mojej szczególnej sytuacji jest to po prostu ważniejsze niż przyjemny projekt. Kod nie może być refaktoryzowany. –

Odpowiedz

4

W duchu zapewniając możliwych rozwiązań (i wbrew temu moje komentarze powyżej) można spróbować jednego z Opcji 1

If TestClass następujące

implementuje interfejs można osiągnąć podobny test stosując andDelegateTo() jak opisane w tym poście, że mówi o Easymock not supporting spying

Opcja 2

Usuń swoją potrzebę szpiegowania, rozszerzając zakres TestClass specjalnie dla potrzeb testowania. Jest to wspólne podejście do rozwiązywania problemów ze starszymi podstawami kodu, w których nie można zmienić testowanego kodu.

Użyję Mockito w tym przykładzie, aby był zgodny z twoim pytaniem, jednak koncepcja będzie działać tak samo z Easymock.

public class TestClassUsingMockito { 
    /** 
    We extend the original class under test so that we can override the creation of IndexData and 
    thereby remove the responsibility of creating this object from the @Test method 
    */ 
    private class ClassForTesting extends TestClass { 

     private Lock lock; 
     private IndexData indexData; 

     public ClassForTesting(IndexData indexData, Lock lock) { 
      this.indexData = indexData; 
      this.lock = lock; 
     } 

     @Override 
     protected IndexData getIndex(InputClass input) { 
      return indexData; 
     } 
    } 

    /** 
    Look Ma' no more Spys! 
    */ 
    @Test 
    public void testAddUsesWriteLock() {   
     // Prepare 
     final Lock lock = Mockito.mock(Lock.class); 
     final IndexData indexData = Mockito.mock(IndexData.class); 
     Mockito.doReturn(lock).when(indexData).getWriteLock(); 
     // ... now use your new subclass for testing 
     final TestClass objectUnderTest = new ClassForTesting(indexData, lock); 
     final InputClass input = Mockito.mock(InputClass.class); 

     // Invoke method under test 
     objectUnderTest.add(input); 

     // Verify 
     Mockito.verify(indexData).getWriteLock(); 
     Mockito.verify(indexData, Mockito.never()).getReadLock(); 
     Mockito.verify(lock).lock(); 
     Mockito.verify(lock).unlock(); 
    } 
} 

Jaki jest analogonem z Mockito.spy/doReturn w EasyMock?

Więc po usunięciu potrzebę Spy() w testach Mockito zadzwonić

Mockito.doReturn(lock).when(indexData).getWriteLock(); 

mogą być napisane w EasyMock jak

expect(indexData.getWriteLock()).andStubReturn(lock); 

EasyMock przykład tego samego testu Mockito powyżej

public class TestClassUsingEasymock extends EasyMockSupport { 

    private class ClassForTesting extends TestClass { 

     private Lock lock; 
     private IndexData indexData; 

     public ClassForTesting(IndexData indexData, Lock lock) { 
      this.indexData = indexData; 
      this.lock = lock; 
     } 

     @Override 
     protected IndexData getIndex(InputClass input) { 
      return indexData; 
     } 
    } 


    @Test 
    public void testAddUsesWriteLock() { 
     // Prepare 
     final Lock lock = createNiceMock(Lock.class);  
     final IndexData indexData = createNiceMock(IndexData.class); 
     EasyMock.expect(indexData.getWriteLock()).andStubReturn(lock); 

     // ... now use your new subclass for testing 
     final TestClass objectUnderTest = new ClassForTesting(indexData, lock); 
     final InputClass input = createNiceMock(InputClass.class); 

     lock.lock(); 
     EasyMock.expectLastCall(); 

     lock.unlock(); 
     EasyMock.expectLastCall(); 

     replayAll(); 

     // Invoke method under test 
     objectUnderTest.add(input); 

     // Verify 
     verifyAll(); 
    } 
} 
+0

Dzięki. Przekażę tę nagrodę, jeśli podasz przykład kodu EasyMock. Już widziałem gdzie indziej rozwiązanie podobne do tego, co sugerujesz, ale również zostało napisane w Mockito i jestem zbyt głupi, aby zmapować 'Mockito.doReturn (lock) .when (indexData) .getWriteLock();' na EasyMock. –

+0

W EasyMock użyj 'expect (indexData.getWriteLock()). AndStubReturn (blokada);' – Brad

+0

Przykład EasyMock dodano – Brad