我正在为我的服务层编写单元测试。我的服务层有多个自动生成的字段。我想只模拟其中一个和其他初始化为自动驾驶。
服务接口
public interface ProductSupplierService {
Map<String, List<? extends BaseDTO>> getProductSuppliers(Long productId, Long tenantId);
ProductSupplierDTO addProductSupplier(Long productId, Long tenantId, ProductSupplierDTO productSupplierDTO);
ProductSupplierDTO editProductSupplier(Long productId, Long supplierId, Long tenantId,
ProductSupplierDTO productSupplierDTO);
void deleteProductSupplier(Long productId, Long supplierId, Long tenantId);
}
服务实现
@Service
public class ProductSupplierServiceImpl implements ProductSupplierService {
private MapperFacade mapper;
@Autowired
public void setMapperFactory(MapperFactory mapperFactory) {
this.mapper = mapperFactory.getMapperFacade();
}
@Autowired
private ProductRepository productRepository;
@Autowired
private ProductManager productManager;
private static final Logger log = LoggerFactory.getLogger(ProductSupplierServiceImpl.class);
@Override
public Map < String, List << ? extends BaseDTO >> getProductSuppliers(Long productId, Long tenantId) {
Product product = fetchProductByProductIdAndTenantId(productId, tenantId);
ListResponse listResponse = new ListResponse();
if (CollectionUtil.nonNullNonEmpty(product.getProductSuppliers())) {
List < ProductSupplierDTO > productSupplierDTOS = new ArrayList < > (0);
product.getProductSuppliers().stream().filter(Objects::nonNull)
.forEach(productSupplier - > productSupplierDTOS
.add(productSupplier.toDTO(ProductSupplierDTO.class, mapper)));
listResponse.addResponse("product_suppliers", productSupplierDTOS);
}
return listResponse.getResponse();
}
@Override
public ProductSupplierDTO addProductSupplier(Long productId, Long tenantId, ProductSupplierDTO productSupplierDTO) {
Product product = fetchProductByProductIdAndTenantId(productId, tenantId);
ProductSupplier productSupplier = productSupplierDTO.toModel(ProductSupplier.class, mapper);
if (product.getProductSuppliers().add(productSupplier)) {
productManager.applyProductSupplier(product, tenantId, productSupplier);
product.setModified(new Date());
try {
productRepository.save(product);
Optional < ProductSupplier > savedProductSupplier = product.getProductSuppliers().stream()
.filter(Objects::nonNull)
.filter(ps - > ps.getSupplierId().equals(productSupplierDTO.getSupplierId())).findFirst();
if (savedProductSupplier.isPresent()) {
return savedProductSupplier.get().toDTO(ProductSupplierDTO.class, mapper);
} else {
throw new UnexpectedException();
}
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new UnexpectedException();
}
} else {
throw new BusinessValidationException("supplier already exists");
}
}
@Override
public ProductSupplierDTO editProductSupplier(Long productId, Long supplierId, Long tenantId,
ProductSupplierDTO productSupplierDTO) {
Product product = fetchProductByProductIdAndTenantId(productId, tenantId);
Optional < ProductSupplier > productSupplierOptional = product.getProductSuppliers().stream()
.filter(Objects::nonNull)
.filter(productSupplier - > productSupplier.getSupplierId().equals(supplierId)).findFirst();
if (productSupplierOptional.isPresent()) {
ProductSupplier productSupplier = productSupplierOptional.get();
if (Objects.nonNull(productSupplierDTO.getBuyPrice())) {
productSupplier.setBuyPrice(productSupplierDTO.getBuyPrice());
}
if (Objects.nonNull(productSupplierDTO.isDefaultSupplier())) {
if (productSupplierDTO.isDefaultSupplier()) {
product.getProductSuppliers().forEach(supplier - > supplier.setDefaultSupplier(false));
productSupplier.setDefaultSupplier(true);
} else {
productSupplier.setDefaultSupplier(false);
}
}
productSupplier.setModified(new Date());
product.setModified(new Date());
try {
productRepository.save(product);
return productSupplier.toDTO(ProductSupplierDTO.class, mapper);
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new UnexpectedException();
}
} else {
throw new EntityNotFoundException(ProductSupplier.class, String.valueOf(supplierId));
}
}
@Override
public void deleteProductSupplier(Long productId, Long supplierId, Long tenantId) {
Product product = fetchProductByProductIdAndTenantId(productId, tenantId);
Optional < ProductSupplier > productSupplierOptional = product.getProductSuppliers().stream()
.filter(Objects::nonNull)
.filter(productSupplier - > productSupplier.getSupplierId().equals(supplierId)).findFirst();
if (productSupplierOptional.isPresent()) {
product.getProductSuppliers().remove(productSupplierOptional.get());
product.setModified(new Date());
try {
productRepository.save(product);
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new UnexpectedException();
}
} else {
throw new EntityNotFoundException(ProductSupplier.class, String.valueOf(supplierId));
}
}
private Product fetchProductByProductIdAndTenantId(Long productId, Long tenantId) {
Product product = productRepository.findByIdAndTenantId(productId, tenantId);
if (Objects.nonNull(product)) {
return product;
} else {
throw new EntityNotFoundException(Product.class, String.valueOf(productId));
}
}
}
测试类
@RunWith(MockitoJUnitRunner.class)
public class ProductSupplierServiceUnitTest {
@Mock
private ProductRepository productRepository;
@Autowired
@InjectMocks
private ProductSupplierServiceImpl productSupplierService;
@Test(expected = EntityNotFoundException.class)
public void productNotFound() {
Mockito.when(productRepository.findByIdAndTenantId(invalidProductId, tenantId)).thenReturn(null);
productSupplierService.getProductSuppliers(invalidProductId, tenantId);
}
@Test
public void getProductSuppliersSuccess() {
initProduct();
initProductSupplier();
Set < ProductSupplier > productSuppliers = new HashSet < > (Collections.singletonList(productSupplierBuilder.get()));
Product product = productBuilder.setProductSuppliers(productSuppliers).get();
product.setId(validProductId);
Mockito.when(productRepository.findByIdAndTenantId(validProductId, tenantId)).thenReturn(product);
Map < String, List << ? extends BaseDTO >> result = productSupplierService.getProductSuppliers(validProductId,
tenantId);
Assert.assertEquals(result.size(), 1);
Assert.assertTrue(result.containsKey("product_suppliers"));
}
@Test
public void getProductSuppliersEmpty() {
initProduct();
initProductSupplier();
Product product = productBuilder.setProductSuppliers(Collections.emptySet()).get();
product.setId(validProductId);
Mockito.when(productRepository.findByIdAndTenantId(validProductId, tenantId)).thenReturn(product);
Map < String, List << ? extends BaseDTO >> result = productSupplierService.getProductSuppliers(validProductId,
tenantId);
Assert.assertTrue(result.isEmpty());
}
}
我只想嘲笑productRepository字段,但不想嘲笑productManager
问题是productManager
是否可以自动初始化它们?就像它们在运行带有完全加载的上下文的Spring引导应用程序时被初始化一样。
要回答来自@Harsh yes的最后一条评论中的问题,您可以为测试配置上下文:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {ExampleTestConfiguration.class})
... 在ExampleTestConfiguration中的@ComponentScan中定义包含和排除的包
如果是“产品经理”
@Spy
ProductManager productManager = new ProductManager();
@Spy
Mapper mapper = new Mapper();
Mockito知道注释为@InjectMocks的@Spy的对象。如果这些类有自己的@autowmed字段,这超出了Mockito的能力,常见的解决方案是使用SpringJUnit4ClassRunner,并在Spring上下文配置中使用Mockito:
<bean id="mockBean" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="some.real.bean.Class" />
</bean>
是模拟抽象类:,而是接口。这是失败点: 如何模拟这段代码?
我使用的是Spring3.1.4.Release和Mockito1.9.5。在我的春季课上,我有: 我想为我的“Defaulturl”字段模拟一个值。请注意,我不想模拟其他字段的值--我希望保持这些字段的原样,只保留“Defaulturl”字段。还要注意,我的类中没有显式的“setter”方法(例如),我不想仅仅为了测试的目的创建任何方法。 既然如此,我如何模拟一个字段的值呢?
我尝试测试一个发送jms消息的类,但无法模拟JmsTemplate JmsProducer.class: JmsProducerTest。类别: 当我运行这个测试用例时,它给了我:java。lang.IllegalArgumentException:对象不是声明类的实例 你对这个问题有什么想法吗?
我想模拟注释来检查根据给定注释返回结果的类的良好行为。 Erg.mockito.exceptions.misusing.WurnTypeOfReturnValue:annotationType()不能返回KClassImpl annotationType()应该返回Class 如果你不确定为什么你会超过错误,请继续阅读。由于语法的性质,上面的问题可能会发生,因为: 此异常可能发生在错误编写的多线程
问题内容: 我有这样的情况 到目前为止我一直在嘲笑 现在我得到一个读者 但是当我执行此行时,我得到null并且无法前进 请告诉我如何嘲笑这个。请注意,我无法更改我的主要代码,因此在我的情况下,Mockito文档中存在的解决方案无效 测试码 问题答案: 要使此工作正常进行,您需要使用Powermockito来拦截构造函数调用(新的InputStreamReader(…),新的BufferedRead
我一直认为Mockito工作某种代理之类的东西。但现在我发现,Mockito允许我做一些像 这不适用于代理。它是如何做到这一点的?这种技术可以用来调用内部AOP方法吗?(请参见Spring AOP不适用于另一个方法中的方法调用)