2013-04-09 6 views

ответ

1

Вы можете сделать это, см. Ответ Мэтта Лахмана. Однако этот подход не рекомендуется. Это немного хаки.

Наилучшим подходом было бы делегировать создание ваших зависимых объектов шаблон фабрики и ввести заводы в свой A класс:

class BFactory { 

    public B newInstance() { 
     return new B(); 
    } 
} 

class CFactory { 

    public C newInstance() { 
     return new C(); 
    } 
} 

class A { 

    private final BFactory bFactory; 
    private final CFactory cFactory; 

    public A(final BFactory bFactory, final CFactory cFactory) { 
     this.bFactory = bFactory; 
     this.cFactory = cFactory; 
    } 

    public void f() { 
     B b = bFactory.newInstance(); 
     C c = cFactory.newInstance(); 
    } 
} 

Вы бы тогда издеваться заводы возвращать фиктивные экземпляры зависимых классов ,

Если по каким-то причинам это не является жизнеспособным, то ваш может создать фабричные методы в A классе

class A { 

    public void f() { 
     B b = newB(); 
     C c = newC(); 
    } 

    protected B newB() { 
     return new B(); 
    } 

    protected C newC() { 
     return newC(); 
    } 
} 

Затем вы можете использовать spy что издевается эти фабричные методы.

+0

Да, как и мой ответ, но с более подробной информацией – AlexWien

+0

Есть только так много способов кошки кошки. И только пара правильных ... –

+1

«Вы не можете» это неправда. PowerMock позволяет вам издеваться над конструкторами. См. Здесь: https://code.google.com/p/powermock/wiki/MockConstructor –

0

Похож, что вам нужно Dependency Injection.

Вы создаете конкретные экземпляры B и C, тогда вы не можете изменить поведение.

Передайте экземпляры в качестве аргумента f(InterfaceB b, InterfaceC c), вы должны использовать полиморфизм, а затем вы можете передать экземпляр mock, поведение которого вам необходимо изменить в качестве аргумента для этого метода. Поэтому методу не нужно заботиться о том, какой тип конкретного экземпляра он передается ему, и вы можете достичь того, что вам нужно.

Я знаю, что имена интерфейсов нелогичны, но это может легко объяснить контекст.

+0

Да, спасибо вам все равно – kimi

+0

@ user988722 Вы получили то, что я предназначил для объяснения? –

+0

Думаю, я получил: 1. Я не могу выполнить свою идею без изменений кода. 2. Мне нужно переопределить мой код, чтобы B и C прошли. Правильно? – kimi

0

Whitout, изменяя код, он не будет работать. (Дизайн для проверки). Вы можете заменить B на заводской метод, который создает B1 в реальном режиме или BTest в тесте, оба реализуют интерфейс IB.

4

Вы можете, по сути, издеваться над проектом, используя PowerMock. У них есть отличная документация для этого прямо здесь: https://code.google.com/p/powermock/wiki/MockConstructor

Также обратите внимание на this example, который проходит через насмешливое строительство объекта.

+1

+1 Конечно, я вижу, что вы можете. Но это не значит, что мы должны это делать. Просто задумайтесь. –

+2

@Narendra OP сказал: «Я не хочу менять свой компактный код по причинам тестирования», что мне кажется совершенно веской причиной для этого. Вместо этого вам кажется, что простой код, который отлично работает, должен быть более сложным, чтобы избежать использования насмешливого инструмента ... –

+0

Многие простые коды, которые отлично работают, не подходят для тестирования. И сделать проверку кода не делает ее сложной. Это экономит ваше время и будущую редизайн. Использование этого взлома powermock не является хорошим способом сделать это и ДОЛЖНО делать только тогда, когда код, создающий экземпляр, не находится под нашим контролем. Я принадлежу к библиотеке или тому подобное. –

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