1

I want to write a test for a printing service. I am using Spring with TestNG and Mockito.

So far I've created a test configuration class for my spring context and the needed test class.

The PrintingService class that i want to test depends on several services, so I've decided to mock them. My problem is that I can't get it working with Spring. Everytime I start the test, spring is throwing an exception

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.printservice.server.message.MessageService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

I thought using the @InjectMocks annotation would solve my problem, but it did not. Maybe I am missunderstanding some aspects, or my idea of testing the service is completly wrong.

PrintingTestConfig

package com.example.printservice;

import com.example.printservice.server.print.PrintingService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;

@Configuration
@ComponentScan(basePackageClasses = {PrintingService.class}, scopedProxy = ScopedProxyMode.TARGET_CLASS)
public class PrintingTestConfig {

  @Bean
  public static PropertySourcesPlaceholderConfigurer propertyConfigIn() {
    return new PropertySourcesPlaceholderConfigurer();
  }

}

PrintingServiceTest

@ContextConfiguration(classes = PrintingTestConfig.class, loader = AnnotationConfigContextLoader.class)
public class PrintingServiceTest extends AbstractTestNGSpringContextTests {

  @Mock
  private MessageService _messageService;

  @Mock
  private ClientCache_clientCache;

  @Mock
  private PrinterCache _printerCache;

  @Value("classpath:example.pdf")
  private Resource _examplePdf;

  @InjectMocks
  private PrintingService _printingService;

  @BeforeMethod
  public void setup() {
    MockitoAnnotations.initMocks(this);
  }

  @Test
  public void printPdf() {
    ...
  }

}
Tobias Timm
  • 1,855
  • 15
  • 27

1 Answers1

0

You can create mock spring beans with the @MockBean annotation. Although I cant see whats under test with Spring you should have your constructors open to keep unit tests simple i.e. constructor DI so it is not tied directly to spring to inject mocks or other implementations.

in the case of more verbose/large tests @MockBean is useful.

Darren Forsythe
  • 10,712
  • 4
  • 43
  • 54