Java 如何使用JUnit测试Spring REST使用者

Java 如何使用JUnit测试Spring REST使用者,java,rest,junit,integration-testing,Java,Rest,Junit,Integration Testing,我正在创建一个基于JavaSpring的微服务应用程序,它使用REST端点进行通信 到目前为止,应用程序本身有一个简单的结构:UIDbLayer。UI模块是api使用者,DBLayer是api提供者 也就是说,我想测试我的UI是否使用JUnit和/或Mockito进行了正确的REST调用。更具体地说,假设我有这样一个服务类: @Service public class AuthorityService { @Autowired private RestTemplate rest

我正在创建一个基于JavaSpring的微服务应用程序,它使用REST端点进行通信

到目前为止,应用程序本身有一个简单的结构:UIDbLayer。UI模块是api使用者,DBLayer是api提供者

也就是说,我想测试我的UI是否使用JUnit和/或Mockito进行了正确的REST调用。更具体地说,假设我有这样一个服务类:

@Service
public class AuthorityService {

    @Autowired
    private RestTemplate restTemplate;

    public Authority getAuthority(String authorityName) {
        Authority authority = 
               restTemplate.getForObject(
                  "http://localhost:8080/authorities/" + authorityName,
                   Authority.class);           
        return authority;
    }
}
public class AuthorityServiceTest {
    private AuthorityService authorityService = new AuthorityService();

    @Test
    public void getAuthorityTest(){
        Assert.assertHttpGETCallMade(
                authorityService.getAuthority("test"),
                "http://localhost:8080/authorities/test");
    }
}
为了测试这个服务方法,我想以某种方式验证是否调用了这个端点。有没有办法包装服务方法并以某种方式断言正在进行的rest GET/POST/PUT等调用

所需的测试类应如下所示:

@Service
public class AuthorityService {

    @Autowired
    private RestTemplate restTemplate;

    public Authority getAuthority(String authorityName) {
        Authority authority = 
               restTemplate.getForObject(
                  "http://localhost:8080/authorities/" + authorityName,
                   Authority.class);           
        return authority;
    }
}
public class AuthorityServiceTest {
    private AuthorityService authorityService = new AuthorityService();

    @Test
    public void getAuthorityTest(){
        Assert.assertHttpGETCallMade(
                authorityService.getAuthority("test"),
                "http://localhost:8080/authorities/test");
    }
}

您可以使用Mockito注入模板,然后验证调用

@ExtendWith(MockitoExtension.class) // RunWith(MockitoJUnitRunner.class) for JUnit 4
public class AuthorityServiceTest {
    @InjectMocks
    private AuthorityService sut;

    @Mock RestTemplate restTemplate;

    @Test
    public void getAuthorityTest(){
        // mock rest call
        Authority auth = mock(Authority.class);
        when(restTemplate.getForObject(any(String.class), any(Class.class)).thenReturn(auth);

        Authority result = sut.getAuthority("test");

        // verify mock result was returned
        assertSame(auth, result);
        // verify call to rest template was performed
        verify(restTemplate).getForObject(
              "http://localhost:8080/authorities/test",
               Authority.class);
    }
}

您可以使用Mockito注入模板,然后验证调用

@ExtendWith(MockitoExtension.class) // RunWith(MockitoJUnitRunner.class) for JUnit 4
public class AuthorityServiceTest {
    @InjectMocks
    private AuthorityService sut;

    @Mock RestTemplate restTemplate;

    @Test
    public void getAuthorityTest(){
        // mock rest call
        Authority auth = mock(Authority.class);
        when(restTemplate.getForObject(any(String.class), any(Class.class)).thenReturn(auth);

        Authority result = sut.getAuthority("test");

        // verify mock result was returned
        assertSame(auth, result);
        // verify call to rest template was performed
        verify(restTemplate).getForObject(
              "http://localhost:8080/authorities/test",
               Authority.class);
    }
}

@npinti如果我理解正确,这将确保REST调用到达api,但是我只想检查调用是否正在进行。这样,即使服务器已关闭/正在开发,测试也不会失败。换句话说,我想为UI创建一种契约测试,从而使测试与服务器(提供者)端分离。删除我的评论。我建议查看Spring提供的测试教程部分:。除此之外,您还可以使用Mockito验证是否使用
verify
方法调用该方法。@npinti如果我理解正确,这将确保REST调用到达api,但是我只想检查调用是否正在进行。这样,即使服务器已关闭/正在开发,测试也不会失败。换句话说,我想为UI创建一种契约测试,从而使测试与服务器(提供者)端分离。删除我的评论。我建议查看Spring提供的测试教程部分:。除此之外,您还可以使用Mockito验证该方法是通过
verify
方法调用的。使用Mockito测试Web层与Spring self的测试库(请参阅:)相比有什么好处?我同意验证使用Mockito调用的方法是否正确。然而,在我看来,在测试web调用时最好使用Spring测试库。@RemcoBuddelmeijer我发布的测试是一个单元测试;它单独测试服务和服务。Spring测试启动Spring上下文,因此它测试的不仅仅是这个服务,还包括应用程序中bean的整个协调。这意味着a)它可能由于其他原因而失败,b)运行可能需要相当长的时间。在您的整体设置中,您应该有两种测试,但它们验证不同的东西。使用Mockito测试Web层与Spring self的测试库(请参阅:)相比有什么好处?我同意验证使用Mockito调用的方法是否正确。然而,在我看来,在测试web调用时最好使用Spring测试库。@RemcoBuddelmeijer我发布的测试是一个单元测试;它单独测试服务和服务。Spring测试启动Spring上下文,因此它测试的不仅仅是这个服务,还包括应用程序中bean的整个协调。这意味着a)它可能由于其他原因而失败,b)运行可能需要相当长的时间。在整个设置中,您应该有两种类型的测试,但它们验证不同的内容。