我有以下服务:
@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中模拟了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();
}
}
}
答案 0 :(得分:1)
根本原因:您没有将ContractService注入ClientService。
我认为您可以使用 ReflectionTestUtils 更轻松地解决问题。这意味着您会将模拟的ContractService注入AccountServiceImpl。
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
答案 1 :(得分:0)
我认为你与clientService的声明相矛盾。
你有:
@Autowired
@InjectMocks
protected ClientService clientService = new ClientServiceImpl();
这应该创建一个名为clientService的自动装配ClientService并注入模拟。然而,= 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)
意味着无需任何进一步的工作就可以创建所有对象。
答案 2 :(得分:0)
@InjectMocks创建该类的实例,并将使用@Mock
注释创建的模拟注入其中。因此,您不必创建ClientService实例,并在其上删除@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.
}
}
答案 3 :(得分:0)
DocumentInfo multipartFile = new DocumentInfo();
multipartFile.setMultipartFileId(1234);
when(this.contractService.getInfo(multipartFile)).thenReturn(multipartFile);
在这里,您希望模拟中的multipartFile
实例不是这种情况,因为在测试期间会有另一个DocumentInfo
实例(请参阅创建它的getInfo
方法)。 / p>
您应该将模拟更改为:
when(this.contractService.getInfo(any())).thenReturn(multipartFile);
在这种情况下,期望将与DocumentInfo的任何实例匹配,而不是您通过构造函数multipartFile = new DocumentInfo();
创建的特定实例