簡體   English   中英

調試時未使用自動裝配初始化 MapStruct 映射器

[英]MapStruct mapper not initialized with autowired when debug

我使用 spring 引導 2.3.2 和 mapstruct。

在服務 class 中,我有一個具有自動裝配注釋的映射器。

@Service
public BillingService{

    private BillingRepository billingRepository;


    @Autowired
    private  BillingMapper billingMapper;   


    @Autowired
    public BillingService (BillingRepository billingRepository){
        this.billingRepository=billingRepository;
    }

    public void getBilling(Long billingId){
        ....
        billingMapper.convertTo(...);
    }

}


@RunWith(MockitoJUnitRunner.class)
public class BillingServiceTest{
    @Mock
    BillingRepository billingRepository;

    private BillingService bilingService;

    @Spy
    private BillingMapper billingMapper = Mappers.getMapper(BillingMapper.class);

    @BeforeEach
    public void setup(){
        MockitoAnnotations.initMocks(this);
        billingService = new BillingService();
    }

    @Test
    public void testGetBilling(){

        List<Billing> billings = new ArrayList<>();
        ...

        List<BillingPayload> payloads = new ArrayList<>();

        when(billingMapper.convertTo(billings)).thenReturn(payloads);     

        bilingService.getBilling(1l);  
    }

}

@Mapper(componentModel="spring")
public interface BillingMapper{
    ...
}

當我調試並且我陷入 BillingService Class 中的 getBilling 方法時,billingMapper 總是 null;

您正在使用非常奇怪的配置。 首先,您有返回BillingService的方法,該方法未指定任何返回值,因此甚至無法編譯。 我建議以下方式:

@Service
public BillingService{

    private final BillingRepository billingRepository;
    private final BillingMapper billingMapper;

    // constructor with bean injection
    public BillingService(final BillingRepository billingRepository,
                          final BillingMapper billingMapper) {
        this.billingRepository = billingRepository;
        this.billingMapper = billingMapper;
    }

    public void getBilling(Long billingId){
        ....
        billingMapper.convertTo(...);
    }

}

然后你可以像下面這樣配置你的測試:

@RunWith(SpringJUnit4ClassRunner.class)
public class BillingServiceTest {

    @Spy private BillingMapper billingMapper = Mappers.getMapper(BillingMapper.class);
    @MockBean private BillingRepository billingRepository;
    @Autowired private BillingService billingService;

    @TestConfiguration
    static class BillingServiceTestContextConfiguration {
        @Bean public BillingService billingService() {
            return new BillingService(billingRepository, billingMapper);
        }
    }

    @Test
    public void testGetBilling(){
        List<Billing> billings = new ArrayList<>();
        ...
        List<BillingPayload> payloads = new ArrayList<>();
        when(billingRepository.findById(1L)).thenReturn(); // someResult
        when(billingMapper.convertTo(billings)).thenReturn(payloads);
        bilingService.getBilling(1l);  
    }
}

@Mapper(componentModel="spring")
public interface BillingMapper{
    ...
}

類似的配置應該可以工作。 主要問題是您將@Autowired與 setter/constructor 注入混合(不知道,因為您在BillingService中的奇怪方法。也不知道為什么在嘗試模擬接口時使用@Spy注釋。 @Spy用於模擬實際例如,雖然@Mock是 mocking Class 類型。如果在您的應用程序BillingMapper指定為Bean ,我會堅持使用@MockBean private BillingMapper billingMapper

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM