首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在另一个服务Junit中模拟服务的服务

在另一个服务Junit中模拟服务的服务
EN

Stack Overflow用户
提问于 2017-09-19 14:02:06
回答 4查看 8.1K关注 0票数 6

我有以下服务:

代码语言:javascript
复制
@Service
public class AccountServiceImpl implements AccountService {

    @Autowired
    protected ContractService contractService;

    private void saveInCache(MultipartFile multipartFile) {
        this.contractService.saveInCache(multipartFile);
    }
}

和另一项服务

代码语言:javascript
复制
@Service
public class ClientServiceImpl implements ClientService {

    @Autowired
    protected ContractService contractService;

    private void getInfoOfFile(String multipartFileId) {
        DocumentInfo document = this.contractService.getInfo(multipartFileId);
        ///
    }
}

我有我的Junit

代码语言:javascript
复制
public class ClientControllerTest extends ApiWebTest {

  @Mock
  protected ContractService contractService;

  @Autowired
  @InjectMocks
  protected ClientService clientService = new ClientServiceImpl();

  @Before
  private void setup() {
     MockitoAnnotations.initMocks(this);
  }

  @Test
  private void testGetInfo() {
     // Code
     DocumentInfo multipartFile = new DocumentInfo();
     multipartFile.setMultipartFileId(1234);
     when(this.contractService.getInfo(multipartFile.getMultipartFileId())).thenReturn(multipartFile);

   // Test the Client service 'getInfoOfFile' method.
  }
}

当我在调试模式下运行这个测试时,我看到this.contractService.getInfo(multipartFileId);返回给我'null‘。

在嘲笑中,我哪里错了?

我刚刚在我的JUnit中模拟了ContractService。我甚至还需要模拟AccountServiceImpl吗?

编辑:添加saveInCache和getInfo方法

代码语言:javascript
复制
private DocumentInfo getInfo(String documentId) {
        if (StringUtils.isEmpty(documentId)) {
            return null;
        }
        WriteLock lock = this.readWriteLock.writeLock();
        try {
            lock.lock();
            DocumentInfo cachedDocument = this.documentCache.get(documentId);
            return cachedDocument;
        } finally {
            if (lock != null) {
                lock.unlock();
            }
        }
    }

private DocumentInfo saveInCache(StreamingStorage document) {
        if (document == null) {
            throw new InvalidParameterException("Creative document is required to put into cache.");
        }
        WriteLock lock = this.readWriteLock.writeLock();
        try {
            lock.lock();
            DocumentInfo newCachedDocument = this.documentCache.put(document.getDocumentId(), document);
            return newCachedDocument;
        } finally {
            if (lock != null) {
                lock.unlock();
            }
        }
    }
EN

回答 4

Stack Overflow用户

发布于 2017-09-19 15:29:28

我认为您使用clientService的声明是自相矛盾的。

您必须:

代码语言:javascript
复制
@Autowired
@InjectMocks
protected ClientService clientService = new ClientServiceImpl();

这应该会创建一个名为ClientService的自动连接的clientService并注入mock。然而,= new ClientServiceImpl()将覆盖自动装配,并为您创建一个普通的(我认为!)。此外,@Autowired@InjectMocks也不是同时需要的-你想要创建一个注入了模拟的服务-而不是一个自动连接的对象。

您可以尝试像这样更改您的测试吗:

代码语言:javascript
复制
@RunWith(MockitoJUnitRunner.class)
public class ClientControllerTest extends ApiWebTest {

  @Mock
  protected ContractService contractService;

  @InjectMocks
  protected ClientService clientService;

  @Test
  private void testGetInfo() {
     DocumentInfo multipartFile = new DocumentInfo();
     multipartFile.setMultipartFileId(1234);
     when(this.contractService.getInfo(multipartFile)).thenReturn(multipartFile);

  }
}

添加@RunWith(MockitoJUnitRunner.class)意味着无需您做任何进一步的工作即可创建所有对象。

票数 4
EN

Stack Overflow用户

发布于 2017-09-19 17:27:29

@InjectMocks创建类的一个实例,并将使用@Mock注释创建的模拟注入其中。因此,您不必创建ClientService实例,然后删除其上的@Autowired

您可以使用MockitoJUnitRunner而不是MockitoAnnotations.initMocks(this)。代码更简单。

更改后的Testclass:

代码语言:javascript
复制
@RunWith(MockitoJUnitRunner.class)
public class ClientControllerTest extends ApiWebTest {

    @Mock
    private ContractService contractService;

    @InjectMocks
    private ClientService clientService;

    @Test
    private void testGetInfo() {
       // Code
       DocumentInfo multipartFile = new DocumentInfo();
       multipartFile.setMultipartFileId(1234);

       when(this.contractService.getInfo(multipartFile)).thenReturn(multipartFile);

       // Test the Client service 'getInfoOfFile' method.
    }
}
票数 2
EN

Stack Overflow用户

发布于 2017-09-19 17:38:13

代码语言:javascript
复制
     DocumentInfo multipartFile = new DocumentInfo();
     multipartFile.setMultipartFileId(1234);
     when(this.contractService.getInfo(multipartFile)).thenReturn(multipartFile);

在这里,您希望在模拟中使用multipartFile实例,但事实并非如此,因为在测试过程中会有DocumentInfo的另一个实例(请参阅创建它的getInfo方法)。

你应该把你的mock改成这样:

代码语言:javascript
复制
 when(this.contractService.getInfo(any())).thenReturn(multipartFile);

在这种情况下,期望值将匹配到DocumentInfo的任何实例,而不是您通过构造函数multipartFile = new DocumentInfo();创建的特定实例

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46292928

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档