正确测试Spring服务[重复]

问题描述 投票:3回答:2

这个问题在这里已有答案:

以下测试在NullPointerException线上使用usersRepo.save(user);失败。我相信这是因为当测试进入performProvision()函数时,usersRepo对象是null

但是,当Web服务实际运行并且我的控制器的端点被命中时,一切正常并且数据库已更新。

知道测试失败的原因吗?我的想法是PAutoProvision引用了真正的数据库,而它应该处理内存数据库,所以可能存在某种冲突?我也看到很多不同的例子,注释设置不同,所以我想这也可能是一个问题。

UsersRepo扩展了JpaRepository,其中PAutoProvision是一个SQL表实体。

如果这还不够,我可以提供UsersRepoPAutoProvisionProvisionController课程。

服务:

@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)}

java spring hibernate junit spring-ws
2个回答
3
投票

正如JB Nizet已经说过的那样,UserRepo mock没有注入到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
投票

给出的答案似乎很有用,但万一它可以帮助某人,测试服务在Spring(恕我直言)中并不那么明显。 SpyBean注释证明非常方便:

@RunWith(SpringRunner.class)
public class ProvisionServiceTest {
    @SpyBean
    private ProvisionService provisionService;
}

资料来源:Spring Boot Reference - Testing

© www.soinside.com 2019 - 2024. All rights reserved.