Как мне издеваться над методом поля члена класса? - PullRequest
3 голосов
/ 13 февраля 2012

Я использую Java 6 и Mockito 1.8.5. Я хочу издеваться над методом поля члена класса, но не могу понять, как. У меня есть эти классы ...

public class CacheService implements CacheCallback {

private final Cache cache;
...

public static CacheService getInstance() {
    return INSTANCE;
}

private CacheService() {
    cache = new DefaultCacheImpl();
}

public boolean saveNodes(final Map<Long, XmlNode> nodeMap) {
    ...
    cache.saveNodes(nodeMap);
}
...
}


public class DefaultCacheImpl implements Cache {
...
public void saveNodes(Map<Long, XmlNode> xmlNodes) {
    dao.updateDB(xmlNodes);
}
...
}

Я не могу понять, как смоделировать метод "saveNodes" поля члена кэша. Я высмеиваю метод, описанный ниже, но, поскольку в классе CacheService для этого поля нет установщика, я не могу понять, как ввести свой макет ..

public class PopulateCacheServiceImpl extends RemoteServiceServlet implements PopulateCacheService {
...
public Boolean initCache() { 
    boolean ret = false;
    try {
        setupMocks();
        CacheService.getInstance().startCache();
        PopulateCache.addTestEntriesToCache();
        ret = true;
    } catch (Exception e) {
        e.printStackTrace(System.err);
        ret = false;
    }   // try
    return ret;
}   // initCache

private void setupMocks() { 
    DefaultCacheImpl cache = mock(DefaultCacheImpl.class);
    doAnswer(new Answer<Object>() {
        public Object answer(InvocationOnMock invocation) throws Throwable {
            return null;  
        }
    }).when(cache).saveNodes(Matchers.anyMap());
}   // setupMocks 

}

Есть ли другие способы сделать это с Mockito? Спасибо, Дэйв

Ответы [ 3 ]

3 голосов
/ 13 февраля 2012

Проблема в этой строке:

cache = new DefaultCacheImpl();

Если вы создаете объект кэша внутри вашего CacheService, они тесно связаны. Вы не можете использовать CacheService с другой реализацией кеша.

Вместо этого передайте реализацию кэша конструктору:

public CacheService(Cache cacheImpl) {
    this.cache = cacheImpl;
}

Это позволяет CacheService использовать любую реализацию Cache.

2 голосов
/ 13 февраля 2012

А как насчет создания двух конструкторов? Тот, кто у тебя, останется там. Другой позволит вам передать реализацию Cache и протестировать класс. Новый конструктор может иметь защищенный доступ для ограничения того, какие классы могут его использовать.

1 голос
/ 13 февраля 2012

Если вы можете изменить источник, удалите эти классы из списка.Избавьтесь от cache = new DefaultCacheImpl(); от конструктора, как предложил Sjoerd.

Если вы не можете - используйте PowerMock, чтобы высмеивать конструктор из DefaultCacheImpl.Я должен сказать, что это действительно уродливое решение (единственное, что уродливее - это поддельный статический код инициализации).

Примечание. Ваш код является ответом на популярный вопрос «Зачем мне нужно внедрение зависимостей?».Я думаю, что люди смотрели на такой код, когда изобрели DI.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...