当前位置: 首页 > 知识库问答 >
问题:

在另一个服务中模拟服务的服务JUnit

段恩
2023-03-14

我有以下服务:

@Service
public class AccountServiceImpl implements AccountService {

    @Autowired
    protected ContractService contractService;

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

和其他服务

@Service
public class ClientServiceImpl implements ClientService {

    @Autowired
    protected ContractService contractService;

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

我有我的Junit

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.
  }
}

当我在调试模式下运行这个测试时,我看到这个。合同服务。getInfo(multipartFileId) 正在返回我“null”。

我在嘲弄中错在哪里。

我刚刚在JUnit中嘲笑了ContractService。我还需要模拟AccountServiceImpl吗?

编辑:添加saveInCache和getInfo方法

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();
            }
        }
    }

共有3个答案

廖弘量
2023-03-14
     DocumentInfo multipartFile = new DocumentInfo();
     multipartFile.setMultipartFileId(1234);
     when(this.contractService.getInfo(multipartFile)).thenReturn(multipartFile);

在这里,您希望模拟中有多部分文件的实例,但事实并非如此,因为在测试期间将有另一个文档信息的实例(请参见创建它的方法)。

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

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

在这种情况下,期望值将与DocumentInfo的任何实例相匹配,而不是与您通过构造函数创建的特定实例相匹配

汲品
2023-03-14

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

您可以使用MockitoJUnitRunner而不是MockitoAnnotations。初始化模拟(this)。代码更简单。

更改后的Testclass:

@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.
    }
}
邵凯定
2023-03-14

我想你是在与客户服务的声明相矛盾。

你有:

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

这应该创建一个名为ClientService的自动连线ClientService,并注入模拟。然而,=新的clientserviceinpl()将覆盖自动连接,并为您创建一个普通的自动连接(我想!)。此外,也不需要同时使用Autowired(自动连线)和InjectMock(注入模拟),您要创建的是注入模拟的服务,而不是Autowired对象。

你能试着这样改变你的测试吗:

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

  }
}

添加@RunTo(MockitoJUnitRunner.class)意味着所有对象创建都发生了,而无需您进行任何进一步的工作。

 类似资料:
  • 各位专家下午好, 我需要调用3个REST API的顺序调用,作为单个客户机调用GET/offers的一部分,以检索百货公司不同通道中每种产品的可用报价,如下所示 然后在循环中检索每个并调用第二个API以获得产品 然后在循环中检索每个并调用第三个API以获得提供 最后,整理所有的响应,将报价列表发送给客户。

  • 问题内容: 是否可以在angularJS中将一个服务注入到另一个服务中? 问题答案: 是。遵循angularjs中的常规注入规则。 感谢@simon。最好使用数组注入以避免最小化问题。

  • 我使用CXF、REST服务和Apache Camel实现了以下API。 http://localhost:9090/api/compute http://localhost:9091/api/listaction null IllegalArgumentException:无效的URI:/API/ListAction/API/ListAction。如果您正在转发/桥接httpendpoint,则在

  • 我对Spring MVC中的模拟服务有一个问题: 和测试: 问题是,为什么我从真正的服务而不是模拟中得到公司(公司1,公司2): 更新了测试类,删除了setUp并将@Bean更改为@MockBean,但保留@SpringBootTest并且它可以工作: }

  • 问题内容: 我已经开发了两个Springboot michroservices exservice1和service2。具有service1依赖性的service2微服务。 我在service2 pom文件中添加了service1的依赖关系,并在运行service2时在eclipse中可以正常工作。但是,当我在Jenkins中部署并为service1创建项目(Jenkins Job)并以maven

  • 问题内容: 我有一个和一个。 我想用的。 当我通过注射添加时: 我得到这个嵌套错误: [嵌套] 11592-2018-8-13 11:42:17 [ExceptionHandler] Nest无法解析PlayersService(+,?)的依赖项。请确保索引[1]的参数在当前上下文中可用。 这两个模块均导入。两种服务都在其模块中单独工作。 问题答案: 你要 导出 的是它提供的模块: 然后将导出 模