2

我正在使用 Spock 和 Mockito,并且很难弄清楚如何从 Mocks 中获得价值。

我正在尝试为称为UserResource与 EJB3 服务层通信的 REST 接口构建 RESTful 服务。

EJB3 服务将需要由其他开发人员编写的新方法。因此,我想我会创建一个 Mock 来代替 REST 接口。

Here is my Spock Test:

package commonapi.test

import commonapi.command.request.UserCreateRequest
import commonapi.command.resource.UserResource
import commonapi.response.CommandResponse
import org.mockito.Mock
import org.mockito.MockitoAnnotations

import spock.lang.Specification

import static org.mockito.BDDMockito.given
import static org.mockito.Mockito.*

/**
 * Specification for Create User Command.
 */
class CreateUserTest extends Specification
{

    /**
     * Mocked Resource.
     */
    @Mock
    UserResource mockedUserResource;

    def setup()
    {
        MockitoAnnotations.initMocks(this)
    }

    def "Mocked Resource Create Single User"()
    {
        given:
            UserCreateRequest createRequest = new UserCreateRequest()
            given(mockedUserResource.createUser(createRequest)).willReturn(new CommandResponse())
        when:
            CommandResponse commandResponse = mockedUserResource.createUser(createRequest)
        then:
            commandResponse != null
    }
}

它编译,测试运行(通过)

问题是,我觉得我并没有真正“测试”任何东西。据我所知,Mockito Mocks 只是“空对象”,您可以在其中“设置行为”,即给定 x,将返回 y。

但是,如果我正在设置行为,我实质上是在为特定的 Spock 特征方法编写它们应该如何表现的代码,一旦实现,它可能与真实事物相同,也可能不同。

基本上我是为了测试的目的而建立 Mock 的行为,而不是测试真实的东西。

我想我在如何利用 Mocks 正确测试正在开发的系统方面在概念上有点挣扎。

任何建议或见解将不胜感激。先感谢您!

4

1 回答 1

6

根据您描述的第一部分,我认为您在嘲笑错误的事情。让我重新解释一下您所说的话,以便您了解我是如何理解您的问题的:

  1. 您正在编写一个 REST api。
  2. 其他人正在 EJB 中为其编写业务逻辑
  3. 你想写一些测试来测试你在写什么

在这种情况下,您应该模拟 EJB 代码,而不是 REST 代码。这是纯 java/Mockito 中的一个示例:

package com.sandbox;

import org.junit.Test;
import static org.mockito.Mockito.*;

public class SandboxTest {

    @Test
    public void myTest() {
        Ejb mock = mock(Ejb.class);
        RestApi restApi = new RestApi();
        restApi.setEjb(mock);

        restApi.doLogic();

        verify(mock).logic();
    }

    private static class Ejb {

        public void logic() {

        }
    }

    private static class RestApi {
        private Ejb ejb;

        private void setEjb(Ejb ejb) {
            this.ejb = ejb;
        }

        public void doLogic() {
            ejb.logic();
        }
    }            
}

这里被测系统是RestApi.doLogic. 你的测试看起来应该和这个有点相似。请注意,我没有在测试中直接调用模拟。我通过调用被测系统(RestApi.doLogic())间接调用它。

这与您的示例不同。您真正要测试的只是您正确设置了模拟。总而言之,您应该模拟出被测系统的依赖关系,而不是被测系统。

于 2013-05-20T20:46:56.480 回答