Spring boot 无法在SpringBoot项目的单元测试中注入@Service

Spring boot 无法在SpringBoot项目的单元测试中注入@Service,spring-boot,spring-boot-test,Spring Boot,Spring Boot Test,我有一个@服务,我试图在单元测试中模拟它,但到目前为止我得到了一个空值。在应用程序类中,我指定什么是scanBasePackages。我必须用不同的方式来做吗?谢谢 这是我的服务类,它实现了一个接口: @Service public class DeviceService implements DeviceServiceDao { private List<Device> devices; @Override public List<Device> getDevice

我有一个@服务,我试图在单元测试中模拟它,但到目前为止我得到了一个空值。在应用程序类中,我指定什么是scanBasePackages。我必须用不同的方式来做吗?谢谢

这是我的服务类,它实现了一个接口:

@Service
public class DeviceService implements DeviceServiceDao {

private List<Device> devices;

@Override
public List<Device> getDevices(long homeId) {
    return devices;
}

}

您应该使用spring引导运行程序运行测试

如果要在测试执行期间加载和使用spring上下文,则必须使用spring测试运行程序。
您没有指定任何运行程序,因此它默认使用测试API的运行程序。这里可能是JUnit或TestNG(运行程序的使用取决于指定的
@Test
注释)。
此外,根据测试的逻辑,您希望调用“real” 休息服务:

List response = restTemplate.getForObject(builder.toUriString(), 
List.class);
为了实现它,您应该加载Spring上下文,并通过使用
@springbootest
注释测试来加载Spring引导容器

如果使用Spring引导上下文,要模拟Spring上下文中的依赖关系,不能使用Mockito中的
@mock
,而必须使用Spring引导中的
@MockBean

为了理解两者之间的区别,您可以参考以下内容

请注意,如果您正在使用
@SpringBootTest
注释,则
testrestemplate
将自动可用,并可自动连接到测试中
但请注意,这是容错的。根据您的测试,它可能是合适的或不合适的

因此,您的代码可能如下所示:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class SmartHomeControllerTest {

    private static final String BASE_URL = “..”;

    @Autowired
    private TestRestTemplate restTemplate;

    @MockBean
    private DeviceService deviceService;

    @Test
    public void getHomeRegisteredDevices() throws Exception {        
       ...
    }

作为旁注,请避免使用原始类型作为
列表
,而应使用泛型类型。

我发现了这一点,我正在使用Mockito并使用它来注释我的测试类。这使我能够模拟我试图使用的服务类

@RunWith(MockitoJUnitRunner.class)
 public class SmartHomeControllerTest {..
     @Mock
     private DeviceService deviceService;
  }

尝试使用@InjectMock而不是@Mock

@RunWith(SpringJUnit4ClassRunner.class)  
@SpringBootTest(classes = NotificationApplication.class)  
public class EmailClientImplTest {  
...  
}  
并在
/src/测试/resources/application.yml


祝你好运

我没有修改这个部分。我专注于注射问题。但你可能是对的。我还注意到OP没有对检索到的
列表
做出任何断言。我添加了SpringBootTest和MockBean注释,但现在我得到了一个空上下文:“原因:java.lang.IllegalArgumentException:无法加载带有空'contextLoader'的ApplicationContext。”。考虑用@ CONTRONTIONTION或'CurryTyrErgy注释测试类。
@RunWith(SpringJUnit4ClassRunner.class)  
@SpringBootTest(classes = NotificationApplication.class)  
public class EmailClientImplTest {  
...  
}