0

I'm trying to setup integration tests for the business layer of a spring boot application. The Unit-Tests work fine but integration tests don't work. Here's the basic setup:

// entities
@Entity
Table(name="TOrder")
public class JPAOrder... {
}

@Entity
Table(name="TCustomer")
public class JPACustomer... {
}
// Repository interfaces
@Repository
public interface OrderRepository extends CrudRepository<JPAOrder, Long> {
...
}

@Repository
public interface CustomerRepository extends CrudRepository<JPACustomer, Long> {
...
}
// Business logic
@Service
@Transactional
public class OrderService ... {
...
@Autowired
private CustomerRepository customerRepository;
...
public Order createOrderForCustomer(final Order order, final Customer customer) {
...
}
}
// Test
@RunWith(SpringRunner.class)
@TestPropertySource(locations = "classpath:application-integrationtest.properties")
public class OrderIntegrationTest {

@SpyBean
private OrderRepository orderRepository;

@Autowired
private OrderService orderService;

Order order = orderService.createOrderForCustomer(...);
}

Starting the application gives me this error

java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '...repository.OrderRepository#0': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [...repository.OrderRepository]: Specified class is an interface
...

If I don't use the @SpyBean annotation in the integration test the orderRepository in the OrderService is simply null. I must be missing something really obvious but I can't figure out what. Any suggestions?

user3411565
  • 125
  • 1
  • 9
  • Is OrderService null too? – Branislav Lazic Jan 18 '18 at 20:05
  • No, Autowired works here, just not in dependent classes. – user3411565 Jan 18 '18 at 21:49
  • If you don't annotate an object with Autowired spring cannot do anything about it. For your case you want simply test only business logic part, you can mock dependencies that your business class needs(in this case it is the repository). You can simply annotate your orderRepository with MockBean instead of SpyBean. And in your test methods you should mock beheavior of this repository's used methods with when-then methods of mockito – barbakini Jan 19 '18 at 08:48
  • @barbakini: Like the title says, I want to have an integration test. Mocking the repositories works just fine but I want to be sure that the Services really do what they are supposed to. Not standalone but when they integrate with the services. – user3411565 Jan 20 '18 at 21:56

1 Answers1

1

For me also this exception occured. Please see This Question.

Try changing @TestPropertySource(..) to

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT,
            value={"spring.profiles.active=integrationtest"})

Hope it helps !

rdj7
  • 1,905
  • 4
  • 18
  • 33
  • Your suggestion got me on the right track. I guess I'll have to live with the fact that the web-environment will be loaded (something I would have liked to avoid). – user3411565 Jan 20 '18 at 22:01