以下测试在NullPointerException
行上usersRepo.save(user);
失败。我相信它是因为当测试进入performProvision()
函数时,usersRepo
对象是null
。
但是,当Web服务实际运行并且我的控制器的端点被命中时,一切正常并且数据库已更新。
知道测试失败的原因吗?我的想法是PAutoProvision
引用了真正的数据库,而它应该处理内存数据库,所以可能存在某种冲突?我也看到很多不同的例子,注释设置不同,所以我想这也可能是一个问题。
UsersRepo扩展了JpaRepository,其中PAutoProvision是一个SQL表实体。
如果这还没有足够的信息,我可以在必要时提供UsersRepo
,PAutoProvision
和ProvisionController
类。
服务:
@Service
public class ProvisionService {
@Autowired
private UsersRepo usersRepo;
public String performProvision(UserData userData) {
try {
PAutoProvision user = new PAutoProvision(userData);
usersRepo.save(user); // OOTB CRUD repository functionality of springData to update/insert record data
return String.format("Success: User %s has been added to the database", userData.getUserId());
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.toString());
System.out.println("\n\n Cannot perform the provisioning of the user " + userData.getUserId() + ": \n" + e.toString() + "\n\n");
}
return "problem";
}
}
测试:
@RunWith(SpringRunner.class)
public class ProvisionServiceTest {
private ProvisionService provisionService;
@MockBean
private UsersRepo usersRepo;
@Before
public void setUp(){
provisionService = new ProvisionService();
}
@Test
public void performProvision_shouldPass() {
UserData userData = new UserData("userid", 30, 1, "spot", 1);
try {
String result = provisionService.performProvision(userData);
assertThat(result, is(equalTo("Success: User userid has been added to the database")));
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.toString());
}
}
}
编辑1:
添加@Autowired
并删除setUp()
方法会产生以下结果:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.autoprovision.ProvisionServiceTest': Unsatisfied dependency expressed through field 'provisionService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.autoprovision.ProvisionService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
答案 0 :(得分:3)
正如JB Nizet所说,UserRepo
模拟没有注入到provisionService实例中,因为在使用new
的setUp方法中创建了provisionService实例。
您的测试应如下所示:
@RunWith(SpringRunner.class)
public class ProvisionServiceTest {
@Autowired // let Spring instantiate the instance to test
private ProvisionService provisionService;
@MockBean
private UsersRepo usersRepo;
@Test
public void performProvision_shouldPass() {
UserData userData = new UserData("userid", 30, 1, "spot", 1);
String result = provisionService.performProvision(userData);
assertThat(result, is(equalTo("Success: User userid has been added to the database")));
}
}
答案 1 :(得分:1)
给出的答案似乎很有用,但万一它可以帮助某人,在Spring(IMHO)中测试服务并不是很明显。 SpyBean
注释真的很方便:
@RunWith(SpringRunner.class)
public class ProvisionServiceTest {
@SpyBean
private ProvisionService provisionService;
}