2016-09-26 3 views
3

Класс Site предоставляется мне внешней командой и имеет частный конструктор.Отказывание частного конструктора

public class Site 
{ 
    int id; 
    String brand; 

    private Site(int id, String brand) 
    { 
     this.id = id; 
     this.brand = brand; 
    } 
} 

Класс SiteUtil (контролируется командой) является

public class SiteUtil 
{ 
    public static Site getSite() 
    { 
    Site site; 
    //Logic 
    return site; 
    } 
} 

Данные функции getSite() применяет его логику требует сетевого вызова, поэтому он должен быть издевались. Он не имеет сеттера в настоящее время (возможно, чтобы поддерживать согласованность с источником данных, не уверен)

Я дразнить его следующим образом

Site mockSite = new Site(1,"Google"); 
PowerMockito.when(SiteUtil.getSite(1)).thenReturn(mockSite); 

Код выше конечно компилировать, как доцент я использую общественность конструктор. Решение, которое я прочитал, состояло в том, чтобы высмеять частный конструктор объекта Site. Я, однако в недоумении о том, как сделать это

+0

Вы можете получить доступ к частным лицам с отражением java. – Tokazio

+0

Не могли бы вы уточнить какой-то код или ссылки, на которые я мог бы обратить внимание? –

+0

Ouch. Это ужасный дизайн API. Является ли «внешняя команда» одной в вашей организации или полностью отдельной? – chrylis

ответ

3

Вот как вы могли бы приступить при условии, что ваш код доступа к значению id и brand только через добытчиками (первый раз писать юнит-тесты!):

@RunWith(PowerMockRunner.class) 
public class MyTestClass { 

    @Test 
    @PrepareForTest(SiteUtil.class) 
    public void myTest() throws Exception{ 
     Site mockSite = PowerMockito.mock(Site.class); 
     PowerMockito.when(mockSite.getId()).thenReturn(1); 
     PowerMockito.when(mockSite.getBrand()).thenReturn("Google"); 
     PowerMockito.spy(SiteUtil.class); 
     PowerMockito.when(SiteUtil.getSite()).thenReturn(mockSite); 

     ... 
    } 
} 
1

Как альтернативный подход, есть способ совместимого изменения их API, если вы можете получить управление, чтобы поддержать вас. Вместо того, чтобы прятать сеть Lookups в методе getSite(), экстернализации их в SiteLookupStrategy:

public class SiteUtil { 
    private static SiteLookupStrategy strategy = new DefaultSiteLookupStrategy(); 

    public static Site getSite(int siteNum) { 
     return strategy.lookup(siteNum); 
    } 

    public static void setLookupStrategy(SiteLookupStrategy strategy) { 
     SiteUtil.strategy = strategy; 
    } 
} 

Таким образом, для тестирования, вы можете придать свою собственную (высмеивали) стратегию, но существующие клиентам коды не нужны будут быть изменен. (Это также имеет преимущество, заключающееся в том, что сам поиск проще тестировать для этой группы.)

Смежные вопросы