Мы пишем тесты JUnit для класса, который использует автопроводное соединение Spring для введения зависимости, которая является некоторым экземпляром интерфейса. Так как класс под тестом никогда явно инстанцирует зависимости или передал его в конструкторе, кажется, что JMockit не чувствует себя обязанным инстанцировать его также.
Вплоть до сих пор мы использовали SpringRunner, чтобы иметь зависимости от насмешки Нагрузки пружины для нас, который работает. Две вещи нам не нравится приблизительно это, 1) платформа Spring должна быть загружена и инициализировала, каждый раз запустив тесты, который не точно быстр и 2) мы вынуждены явно создать все ложные зависимости как реальные классы, что-то, что JMockit помогает устранить.
Вот упрощенный пример того, что мы тестируем:
public class UnitUnderTest {
@Autowired
ISomeInterface someInterface;
public void callInterfaceMethod() {
System.out.println( "UnitUnderTest.callInterfaceMethod calling someInterface.doSomething");
someInterface.doSomething();
}
}
Так, вопрос, там способ иметь JMockit, создают насмешку someInterface
?
JMockit всегда инстанцирует высмеянный интерфейс (за исключением случая конечного поля высмеивания), но это происходит только в тестовом коде. Он не будет автоматически вводить экземпляр в тестируемый код.
Вам пришлось бы вводить экземпляр имитации вручную. Например:
public class SomeTest
{
@Autowired UnitUnderTest unitUnderTest;
@Mocked ISomeInterface theMock; // created and assigned automatically
@Test
public void testSomeMethod()
{
Deencapsulation.setField(unitUnderTest, theMock);
//proceed with unit test here
}
}
mockit.Deencapsulation
- это утилита на основе Reflection, которая позволяет вызывать приватные методы, получать/устанавливать поля и т.д.
Вы можете использовать org.springframework.test.util.ReflectionTestUtils
для однозначного введения издевательского ISomeInterface
в вашем тестовом случае.
Смотрите документацию
С любезно предоставленными выше подсказками, вот что я нашел наиболее полезным, как кто-то довольно новый для JMockit: JMockit предоставляет класс Deencapsulation
, позволяющий устанавливать значения приватных зависимых полей (нет необходимости перетаскивать библиотеки Spring), и класс MockUp
, позволяющий явно создавать реализацию интерфейса и имитировать один или несколько методов интерфейса. Вот как я в итоге решил этот конкретный случай:
@Before
public void setUp() {
IMarketMakerDal theMock = new MockUp <IMarketMakerDal>() {
@Mock
MarketMakerDcl findByMarketMakerGuid( String marketMakerGuid ) {
MarketMakerDcl marketMakerDcl = new MarketMakerDcl();
marketMakerDcl.setBaseCurrencyCode( CURRENCY_CODE_US_DOLLAR );
return marketMakerDcl;
}
}.getMockInstance();
setField( unitUnderTest, theMock );
}
Спасибо всем за помощь.