unit-testing - 使用 MockMvc 和 Mockito 测试 Katharsis JsonApi

标签 unit-testing mockito spring-test-mvc katharsis

我想测试我的 Katharsis ResourceRepository (katharsis-spring 2.1.7) 配置的行为:

import io.katharsis.queryParams.QueryParams;
import io.katharsis.repository.ResourceRepository;
import org.springframework.stereotype.Component;

@Component
public class UserResourceRepository implements ResourceRepository<UserDTO, String> {

    @Autowired
    private UserRepository databaseRepository;

    @Override
    public UserDTO findOne(String email, QueryParams queryParams) {
        return null;
    }

    @Override
    public Iterable<UserDTO> findAll(QueryParams queryParams) {
        return null;
    }

    @Override
    public Iterable<UserDTO> findAll(Iterable<String> iterable, QueryParams queryParams) {
        return null;
    }

    @Override
    public void delete(String email) {
    }

    @Override
    public UserDTO save(UserDTO s) {
        return null;
    }
}

我想以与使用普通 Spring Controller 类似的方式测试它,使用 Mockito 模拟数据库存储库并使用 MockMvc:

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import java.util.Optional;

import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@RunWith(MockitoJUnitRunner.class)
public class UserJsonApiTest {

    @InjectMocks
    private UserResourceRepository resourceRepository;

    @Mock
    private UserRepository databaseRepository;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        mockMvc = MockMvcBuilders.standaloneSetup(resourceRepository).build();
    }

    @Test
    public void first() throws Exception {
        Optional<UserEntity> user = Optional.of(new UserEntity().
                id(1).
                email("test@test").
                firstName("test first name").
                lastName("test last name").
                pass("test pass"));

        when(
                databaseRepository.
                        findOneByEmail(user.get().getEmail())).
                thenReturn(user);

        mockMvc.perform(
                get("/users/" + user.get().email())).
                andExpect(status().isOk())
        ;
    }

}

显然,这段代码不起作用,因为我的 Katharsis UserResourceRepository 并不是真正的 Controller 。到目前为止,我(从日志中)了解到它实际上使用了一些过滤器映射和名为 io.katharsis.spring.KatharsisFilterV2 的类。

有没有办法使用MockMvc进行这样的测试?如果没有 - 有没有其他方法可以在不启动整个服务器(带有模拟)的情况下测试它?

最佳答案

您可以使用嵌入式服务器 - 例如 UndertowJaxrsServer - 并注入(inject) KatharsisFeature:

  1. 创建一个扩展应用程序的类 (MyApp) public static class MyApp extends Application {并将其部署到嵌入式服务器server.deploy(MyApp.class);
  2. 在此类中,覆盖 getClasses 并添加实现功能 KatharsisFeatureTest implements Feature 的第二个类 (KatharsisFeatureTest)
  3. 在 KatharsisFeatureTest 中,您可以注册一个 KatharsisFeature,然后您可以覆盖 JsonServiceLocator 并注入(inject)模拟。

听起来有点复杂,但是很有魅力:) 看看我的实现。

.

@RunWith(MockitoJUnitRunner.class)
public class EndpointResourceTest {
    @Mock
    private EndpointService endpointService;

    @InjectMocks
    private final static EndpointResourceV1 endpointRessource = new EndpointResourceV1();

    private static UndertowJaxrsServer server;

    @BeforeClass
    public static void beforeClass() throws Exception {
        server = new UndertowJaxrsServer();
        server.deploy(MyApp.class);
        server.start();
    }


    @Test
    public void testGetEndpoint() throws URISyntaxException {
        Mockito.when(endpointService.getEndpoint("SUBMIT")).thenReturn(new EndpointDTO("SUBMIT", "a", "b"));

        Client client = ClientBuilder.newClient();
        Response response = client.target(TestPortProvider.generateURL("/api/endpoints/SUBMIT"))
                .request(JsonApiMediaType.APPLICATION_JSON_API)
                .get();

        Assert.assertEquals(200, response.getStatus());
        String json = response.readEntity(String.class);
        Assert.assertTrue(json.contains("SUBMIT"));
        Assert.assertTrue(json.contains("a"));
        Assert.assertTrue(json.contains("b"));
        Mockito.verify(endpointService, Mockito.times(1)).getEndpoint("SUBMIT");
    }

    @AfterClass
    public static void afterClass() throws Exception {
        server.stop();
    }

    @ApplicationPath("/api")
    public static class MyApp extends Application {
        @Override
        public Set<Class<?>> getClasses() {
            HashSet<Class<?>> classes = new HashSet<Class<?>>();
            classes.add(KatharsisFeatureTest.class);
            return classes;
        }
    }

    public static class KatharsisFeatureTest implements Feature {
        @Override
        public boolean configure(FeatureContext featureContext) {
            featureContext
                .property(KatharsisProperties.RESOURCE_SEARCH_PACKAGE, "...")
                .register(new io.katharsis.rs.KatharsisFeature(
                    new ObjectMapper(), new QueryParamsBuilder(new DefaultQueryParamsParser()), new SampleJsonServiceLocator() {

                        @Override
                        public <T> T getInstance(Class<T> clazz) {
                            try {
                                if (clazz.equals(EndpointResourceV1.class)) {
                                    return (T) endpointRessource;
                                }

                                return clazz.newInstance();
                            }
                            catch (InstantiationException | IllegalAccessException e) {
                                throw new RuntimeException(e);
                            }
                        }

                    }));

            return true;
        }
    }

}    

关于unit-testing - 使用 MockMvc 和 Mockito 测试 Katharsis JsonApi,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35159206/

相关文章:

unit-testing - 测试持续集成的分支是什么?

android - 如何运行协程作为单元测试的阻塞?

java - 我可以 stub 使用 Mockito 通过反射调用的方法吗?

java - 当我运行单一测试时,内存中的 H2 是空的,但当我运行应用程序本身时,它会被填充

testng - 如何为独立 MockMvc 启用 Controller 参数验证

Spring test-mvc PUT 不支持

c# - 如何确定下拉列表是否折叠?

python - Python 中的单元测试是否有最小样式?

linux - Shell (Bash) 脚本的测试与分析?

android - Robolectric = Mockito : Cannot Create Mock or Spy In Mockito Because: dexcache == null