如何在Mockito嘲笑部分字段



我正在为我的服务层编写单元测试。我的服务层有多个自动的字段。我只想嘲笑其中一个和其他人以自动化为初始化。

服务接口

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

我只想嘲笑生产预处理领域,但是Productmanager&amp;映射器字段必须自动初始化。

问题是Productmanager&amp;运行测试时,映射器字段为null。

是否可以自动初始化它们?就像在运行带有满载上下文的Spring Boot应用程序时初始化它们一样。

如果" productmanager"&amp;"映射器"是简单的类,只需添加:

@Spy
ProductManager productManager = new ProductManager();
@Spy
Mapper mapper = new Mapper();

Mockito知道用@Spy @injectMocks注释的对象。如果这些类具有@autowiend的字段,则超出了Mockito的功能,而常见解决方案是使用SpringJunit4ClassRunner并在弹簧上下文中使用Mockito:

<bean id="mockBean" class="org.mockito.Mockito" factory-method="mock">
    <constructor-arg value="some.real.bean.Class" />
</bean>

在@harshit的最后一个评论中回答问题,您可以为您的测试配置上下文:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {ExampleTestConfiguration.class})

...在expletestConfiguration中的@componentscan中定义您的包含和排除的软件包

相关内容

  • 没有找到相关文章

最新更新