Spring @ Custom constructor causes @Value to return null when instantiating in a test class

I use an auto-host constructor in a service that, when instantiated in a test class, @Value annotations return null. Autowiring dependencies directly solves the problem, but the project follows the agreement to use auto-install based on the constructor. I understand that instantiating a service in a test class does not create it from the Spring IoC container, which causes @Value to return null. Is there a way to create a service from an IoC container using constructor-based autoinstallation without direct access to the application context?

Service example:

@Component
public class UpdateService {

   @Value("${update.success.table}")
   private String successTable;

   @Value("${update.failed.table}")
   private String failedTable;

   private UserService userService

   @Autowired
   public UpdateService(UserService userService) {
      this.userService = userService;
   }
}

Test Service Example:

@RunWith(SpringJUnite4ClassRunner.class)
@SpringApplicationConfiguration(classes = {TestApplication.class})
@WebAppConfiguration
public class UpdateServiceTest {

   private UpdateService updateService;

   @Mock
   private UserService mockUserService;

   @Before
   public void setUp() {
      MockitoAnnotations.initMocks(this);

      updateService = new UpdateService(mockUserService);

   }
}
+4
2

@Value updateService, spring.

spring :

...
public class UpdateServiceTest  { 
    @Autowired 
    private UpdateService updateService;
    ...

Mock userService

userService protected , .

@Before
public void setUp() {
   MockitoAnnotations.initMocks(this);

   updateService.userService = mockUserService;
}

Whitebox:

@Before
public void setUp() {
   MockitoAnnotations.initMocks(this);

   Whitebox.setInternalState(updateService, 'userService', mockUserService);
}
+2

@Value , spring. UpdateService , .

. spring. @Value ReflectionTestUtils.setField() ( ):

public class UpdateServiceTest {

   @InjectMocks
   private UpdateService updateService;

   @Mock
   private UserService mockUserService;

   @Before
   public void setUp() {
      MockitoAnnotations.initMocks(this);
      ReflectionTestUtils.setField(updateService, "successTable", "my_success");
      updateService.failedTable = "my_failures";
   }
}

spring.

, (@Primary , - ), , .

@RunWith(SpringJUnite4ClassRunner.class)
@SpringApplicationConfiguration(classes = {TestApplication.class, UpdateServiceTest.TestAddOn.class})
@WebAppConfiguration
public class UpdateServiceTest {

   @Autowired
   private UpdateService updateService;

   private static UserService mockUserService;



   static class TestAddOn {
      @Bean
      @Primary
      UserService updateService() {
        mockUserService = Mockito.mock(UserService.class);
        return mockUserService;
      }
   }
}
+2

All Articles