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



我有以下服务:

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

当我以调试模式运行此测试时,我看到this.contractService.getInfo(multipartFileId);正在返回我的" null"。

嘲笑我要在哪里出错。

我刚刚嘲笑我的Junit中的合同服务。我是否还需要嘲笑councorserviceimpl?

编辑:添加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();
            }
        }
    }

我认为您与客户服务的声明相矛盾。

您有:

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

这应该创建一个称为ClienterVice的自动客户服务,并注入模拟。但是,= new ClientServiceImpl()然后将覆盖自动启动,并为您创建一个普通的香草(我认为!)。另外,@Autowired@InjectMocks也不需要同时 - 您想创建一个模拟注入的服务 - 不是自动对象。

您可以尝试这样更改测试:

@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)表示所有对象创建都会发生,而无需您的任何进一步的工作。

@injectMocks创建了类的实例,并将用@Mock注释创建的模拟注入其中。因此,您无需创建客户服务的实例,而是在其上删除@Autowired

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

更改后的测试类:

@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.
    }
}
     DocumentInfo multipartFile = new DocumentInfo();
     multipartFile.setMultipartFileId(1234);
     when(this.contractService.getInfo(multipartFile)).thenReturn(multipartFile);

在这里您期望在模拟中使用multipartFile实例,这不是事实,因为在测试过程中将有另一个DocumentInfo的实例(请参阅创建它的getInfo方法)。

您应该将模拟更改为这样的事情:

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

在这种情况下,期望将与您通过构造函数multipartFile = new DocumentInfo();

创建的任何特定实例与任何特定实例进行匹配。

根本原因:您没有将合同服务注入客户服务。

我认为您可以使用 REFLECTIONTESTUTITILS 更容易解决问题。这意味着您将向AccounterviceImpl注入模拟的合同服务。

public class ClientControllerTest extends ApiWebTest {
  protected ClientService clientService = new ClientServiceImpl();
  private ContractService contractService;
  @Test
  private void testGetInfo() 
  {
     // Code
     DocumentInfo multipartFile = new DocumentInfo();
     multipartFile.setMultipartFileId(1234);
     contractService= EasyMock.createNiceMock(ContractService.class);
     ReflectionTestUtils.setField(clientService, "contractService", contractService);
     EasyMock.expect(contractService.getInfo(multipartFile.getMultipartFileId())).andReturn(multipartFile).anyTimes();
     EasyMock.replay(contractService);
  }
}

您可以将其应用于Junit

相关内容

  • 没有找到相关文章

最新更新