I'm having problems trying to unit test a maven multi-module project with Spring.
I've 4 modules:
application-core
application-data
application-service
application-web
This is my test, its in the application-core module:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:/config/application-context.xml")
public class TicketTest {
@Mock
ITicketDAO ticketDAO;
@Autowired
@InjectMocks
ITicketCore ticketCore;
@Before
public void init() {
MockitoAnnotations.initMocks(this);
}
@Test
public void testRegisterTicket_Ticket_NotUsed_isValid() {
Long ticketNumber = 0L;
when(ticketDAO.getTicket(anyLong())).thenReturn(null);
final boolean isValidTicket = ticketCore.validateTicket(ticketNumber);
assertTrue(isValidTicket);
}
}
And here is the implementation:
@Component
@Scope("prototype")
public class TicketCore implements ITicketCore{
private ITicketDAO ticketDao;
@Autowired
public TicketCore(ITicketDAO ticketDao) {
this.ticketDao = ticketDao;
}
@Override
public boolean validateTicket(Long ticketNumber) {
ITicket ticket = ticketDao.getTicket(ticketNumber);
return ticket != null;
}
}
Interface:
public interface ITicketDAO {
ITicket getTicket(Long ticketNumber);
}
Implementation of ITicketDAO its on the application-data module:
@Service
public class TicketDAO implements ITicketDAO {
@Override
public ITicket getTicket(Long ticketNumber) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
}
I'm having problems testing this code because the context doesn't find the implementation of ITicketDAO. It's seems obvious, because when the test are running, JUnit doesn't care about putting in the classpath the "others modules".
Spring throws BeanCreationException for obvious reasons.
Am I right?
So I would like to test my project without Spring getting in the tests' way.
What could I do to get my tests run w/o any problem???
I've created dummy classes in the test folder/packages, and it works, but...
I would eventually have ALL the external implementations in my application-core module's test folder.
There is a better way?
Thanks in advance.
UPDATE:
application-data
application-service
application-web
all of them depends on application-core. Spring successfully inject TicketCore(application-core). What I want is to give Spring "something" (a dummy class) to inject in ITicketDAO just to run the test.
<beans>
<context:component-scan base-package="ve.gov.imat.transimat" />
<context:annotation-config />
<aop:config proxy-target-class="true" />
</beans>
Pretend that each Maven module is a completely separate project. Put tests specifically of each module's code inside it, and add integration tests in the module where all of the dependencies necessary to run them have been included.
You haven't provided any information on the dependencies between your modules, but it appears that the problem you're running into is that you need some implementation of an interface for testing purposes, but your production bean is defined in another module. This is what mocking frameworks like EasyMock and Mockito are for; they allow you to write simple placeholder implementations so that you can test TicketCore specifically, and it's a good idea to use them even when the real implementation is available so that you can be sure you're just testing one component at a time.
In TicketTest, you're correctly defining your Mockito mock for ITicketDAO, but your TicketCore is still trying to autoacquire the bean from Spring, even though you haven't registered it. Either manually register your bean into the test context, or place the definition for the mock in an @Configuration in src/test.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With