我在一个服务中使用了一个自动连接的构造函数,当在测试类中实例化时,它会导致@Value注释返回null。自动关联依赖项直接解决了这个问题,但项目遵循使用基于构造函数的自动关联的惯例。我的理解是,在测试类中实例化服务并不是从Spring IoC容器创建服务,这会导致@Value返回null。有没有一种方法可以使用基于构造函数的自动连接从IoC容器创建服务,而不必直接访问应用程序上下文?
示例服务:
@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;
}
}
测试服务示例:
@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);
}
}
@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前完成。
为此,我添加了一个提供mock用户服务的内部配置类(仅当您的上下文中有任何其他用户服务时,@Primary
才适用),mock存储在这里的一个静态成员中,以便在以后的测试中简单地访问mock。
@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;
}
}
}
要使@Value
工作updateService
应该在spring上下文中。
Spring框架集成测试的最佳实践是在测试上下文中包含应用程序上下文,并在测试中自动装配测试源:
...
public class UpdateServiceTest {
@Autowired
private UpdateService updateService;
...
模拟用户服务
选项,将userService
更改为protected
,并考虑测试类和源类在同一个包中。
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
updateService.userService = mockUserService;
}
选项与反射与白盒:
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
Whitebox.setInternalState(updateService, 'userService', mockUserService);
}
问题内容: 到目前为止,我在构造函数中有一个类 的功能是在数据库中查找特定的电子邮件地址。当我将标识符设置为某些电子邮件时,我确定它不在数据库中;第一个IF被传递,并转到第一个ELSE。这里的构造函数应该返回FALSE; 但是,它返回具有所有NULL值的类的对象! 我如何防止这种情况?谢谢 编辑: 谢谢大家的回答。那太快了!我看到OOP方式是抛出异常。因此,抛出一个问题,我的问题发生了变化,我应该
我是Spring的新手。我创建了一个bean类和一个配置文件,如下所示: Beans.xml Employee.java 当我尝试使用Application Context获取bean时,它会给出以下异常: 线程“main”组织中出现异常。springframework。豆。工厂BeanCreationException:创建在类路径资源[Problem.xml]中定义的名为“employee”的
问题内容: 如何从Java的构造函数中获取实例化对象? 我想为某些GUI类存储对父对象的引用,以模拟事件冒泡-调用父处理程序-但我不想更改所有现有代码。 问题答案: 简短的回答:Java没有办法做到这一点。(您可以找到哪个班级叫您,但以下较长的答案在大多数情况下也适用于您。) 长话大说:依赖于被调用的地方,魔术地表现不同的代码几乎总是一个坏主意。这会使必须维护您代码的人感到困惑,并且严重损害了您的
我有一个用@service注释的类(HttpHandler)。我正在为这个服务类编写单元测试用例。我在测试类中使用@Autowired注释来获取服务的对象。但是,当我运行单元测试时,它返回NullPointerException。有人能帮帮我吗? 下面是服务类的代码:
问题内容: 我有这个代码。对象构造函数是否有可能以某种方式失败,从而为它分配了一个值,并在构造函数返回后释放了该对象? 问题答案: 假设您使用的是PHP 5,则可以在构造函数中引发异常: 为了清楚起见,您可以将其包装在静态工厂方法中: 顺便说一句,某些版本的PHP 4允许您在构造函数中将$ this设置为NULL,但我认为这从未得到正式批准,并且最终删除了“功能”。
测试时,我在使用application.properties值时遇到问题。 这是我的代码: 这和预期的一样工作。它用在我的updateSubscription方法中,正确的值来自application.properties 问题出在我的测试中,当我使用这个类时,这个值没有被实例化并抛出一个错误 但这会引发错误:lateinit属性defaultPackageForFCMInstance尚未初始化