我有以下服务:
@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();
}
}
}发布于 2017-09-19 15:29:28
我认为您使用clientService的声明是自相矛盾的。
您必须:
@Autowired
@InjectMocks
protected ClientService clientService = new ClientServiceImpl();这应该会创建一个名为ClientService的自动连接的clientService并注入mock。然而,= 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)意味着无需您做任何进一步的工作即可创建所有对象。
发布于 2017-09-19 17:27:29
@InjectMocks创建类的一个实例,并将使用@Mock注释创建的模拟注入其中。因此,您不必创建ClientService实例,然后删除其上的@Autowired。
您可以使用MockitoJUnitRunner而不是MockitoAnnotations.initMocks(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.
}
}发布于 2017-09-19 17:38:13
DocumentInfo multipartFile = new DocumentInfo();
multipartFile.setMultipartFileId(1234);
when(this.contractService.getInfo(multipartFile)).thenReturn(multipartFile);在这里,您希望在模拟中使用multipartFile实例,但事实并非如此,因为在测试过程中会有DocumentInfo的另一个实例(请参阅创建它的getInfo方法)。
你应该把你的mock改成这样:
when(this.contractService.getInfo(any())).thenReturn(multipartFile);在这种情况下,期望值将匹配到DocumentInfo的任何实例,而不是您通过构造函数multipartFile = new DocumentInfo();创建的特定实例
https://stackoverflow.com/questions/46292928
复制相似问题