Как правильно издеваться над двумя классами, реализующими интерфейс с Mockito?

У меня есть 2 класса, которые реализуют один интерфейс.

public interface DataAccess { /*....*/ }
public class DataAccessCache implements DataAccess { /*...*/ }
public class DataAccessMemory implements DataAccess { /*...*/ }

Теперь у меня есть еще один класс с именем CPU, который инкапсулирует DataAccessCache и DataAccessMemory (оба являются частными переменными экземпляра), например:

private DataAccessCache cache;
private DataAccessMemory memory;

Чтобы издеваться над этими двумя классами, у меня есть 2 метода установки:

public void setDataAccessCache( DataAccessCache cache ) {
    this.cache = cache;
}

public void setDataAccessMemory( DataAccessMemory memory ) {
    this.memory = memory;
}

Я хочу протестировать метод ЦП put(String key, String value), который поместит key-value пару в память и кеш. Я хочу убедиться, что метод put кеша и метод put памяти вызываются внутри метода put процессора. Я тестирую так (используя Mockito):

public void test() {
    CPU cpu = new cpu();
    DataAccessCache cache = mock( DataAccessCache.class );
    DataAccessMemory memory = mock( DataAccessMemory.class );
    when( cache.put("key", "value") ).thenReturn(true);
    when( memory.put("key", "value") ).thenReturn(true);
    cpu.setDataAccessCache( cache );
    cpu.setDataAccessMemory( memory );
    cpu.put("key", "value");
    verify( cache ).put("key", "value");
    verify( memory ).put("key", "value");
}

Однако в результате теста указано, что произошла ошибка:

java.lang.NullPointerException
at CPU.put(Unknown Source)
at CPUTest.test(Unknown Source)

Как я могу сделать это правильно?


person knd    schedule 13.11.2012    source источник
comment
Трудно сказать без кода для CPU.put()   -  person Peter Svensson    schedule 14.11.2012
comment
Ты прав, Питер. Поскольку я реализую CPU.put(), у него есть система блокировки для взаимных исключений. Это означает, что есть части, которые я должен заблокировать (acquire()) и release(). Проблема в том, что я не издевался над этими блокировками, и вот мы здесь, CPU.put() не может продолжить работу. Спасибо.   -  person knd    schedule 14.11.2012
comment
Нет проблем - рад, что вы его нашли   -  person Peter Svensson    schedule 14.11.2012


Ответы (2)


Вы должны просто проверить свои моки в конце.

   public void test() {
    CPU cpu = new cpu();
    DataAccessCache cache = mock( DataAccessCache.class );
    DataAccessMemory memory = mock( DataAccessMemory.class );
    cpu.setDataAccessCache( cache );
    cpu.setDataAccessMemory( memory );
    cpu.put("key", "value");
    verify( cache ).put("key", "value");
    verify( memory ).put("key", "value");
}
person ShyJ    schedule 13.11.2012
comment
Спасибо, что попробовали ShyJ. Это не проблема, которую вы здесь указываете. Прочитайте комментарий выше. - person knd; 14.11.2012

Попробуйте это так:

public void test() {
    CPU cpu = new cpu();
    DataAccessCache cache = spy( new DataAccessCache() );
    DataAccessMemory memory = spy( new DataAccessMemory() );
    //when( cache.put("key", "value") ).thenReturn(true);
    doReturn(true).when(cache).put(eq("key"), eq("value"));
    //when( memory.put("key", "value") ).thenReturn(true);
    doReturn(true).when(memory).put(eq("key"), eq("value"));
    cpu.setDataAccessCache( cache );        
    cpu.setDataAccessMemory( memory );
    cpu.put("key", "value");
    verify( cache ).put("key", "value");
    verify( memory ).put("key", "value");
}

Я не помещал это в IDE, просто набрал с головы, но думаю, что понял правильно. Попытайся.

person Sinisha Mihajlovski    schedule 13.11.2012