java 在springboot上进行JOOQ测试时出现UnsatisfiedDependencyException

hjzp0vay  于 2023-06-20  发布在  Java
关注(0)|答案(1)|浏览(95)

bounty将在5天内到期。此问题的答案有资格获得+50声望奖励。Paulo Henrique想要吸引更多的注意力到这个问题上:我需要一种方法来正确地实现这个自动化测试

我有这个基本的CRUD API使用springboot版本2.7.10和JOOQ 3.14,它有一些以前编写的测试,但它们不工作,因为我没有JOOQ和tesccontainer的经验,我不能指出问题所在,但我将显示用于复制错误的代码,该错误是org.springframework.beans.factory.UnsatisfiedDependencyException
首先我有这个模型类(不幸的是我不能使用lombok):

package com.data.platform.core.models;

import java.util.Date;
import java.util.UUID;

public class Owner {
    private UUID ownerId;
    private String ownerName;
    private String ownerEmail;
    private Date updatedAt;
    private Date createdAt;

    public Owner() {
    }

    public Owner(UUID ownerId, String ownerName, String ownerEmail, Date updatedAt, Date createdAt) {
        this.ownerId = ownerId;
        this.ownerName = ownerName;
        this.ownerEmail = ownerEmail;
        this.updatedAt = updatedAt;
        this.createdAt = createdAt;
    }

    public UUID getOwnerId() {
        return ownerId;
    }

    public void setOwnerId(UUID ownerId) {
        this.ownerId = ownerId;
    }

    public String getOwnerName() {
        return ownerName;
    }

    public void setOwnerName(String ownerName) {
        this.ownerName = ownerName;
    }

    public String getOwnerEmail() {
        return ownerEmail;
    }

    public void setOwnerEmail(String ownerEmail) {
        this.ownerEmail = ownerEmail;
    }

    public Date getUpdatedAt() {
        return updatedAt;
    }

    public void setUpdatedAt(Date updatedAt) {
        this.updatedAt = updatedAt;
    }

    public Date getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }
}

然后我有这个repository类:

package com.data.platform.core.repository.impl;

import com.data.platform.core.dto.requests.OwnerDtoRequest;
import com.data.platform.core.entity.operation.tables.Owners;
import com.data.platform.core.models.Owner;
import com.data.platform.core.converters.OwnerConverter;
import com.data.platform.core.Repository.OwnerRepository;
import org.jooq.DSLContext;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Optional;
import java.util.UUID;

@Repository
public class OwnerRepositoryImpl implements OwnerRepository {
    
    @Autowired
    private DSLContext dslContext;

    @Autowired
    private OwnerConverter ownerConverter;

    @Override
    public List<Owner> findAll(Integer size, Integer offset) {

        return dslContext.selectFrom(Owners.OWNERS)
                .limit(size)
                .offset(offset)
                .fetch(ownerConverter);
    }

    @Override
    public Optional<Owner> findById(UUID ownerId) {

        return dslContext.selectFrom(Owners.OWNERS)
                .where(Owners.OWNERS.OWNER_ID.eq(ownerId))
                .fetch().map(ownerConverter).stream().findFirst();
    }

    @Override
    public Owner insert(OwnerDtoRequest owner) {

        return dslContext.insertInto(Owners.OWNERS)
                .set(Owners.OWNERS.OWNER_NAME, owner.getOwnerName())
                .set(Owners.OWNERS.OWNER_EMAIL, owner.getOwnerEmail())
                .returning()
                .fetchOne()
                .map(ownerConverter);
    }

    @Override
    public Owner update(UUID ownerId, OwnerDtoRequest owner) {

        return dslContext.update(Owners.OWNERS)
                .set(Owners.OWNERS.OWNER_NAME, owner.getOwnerName())
                .set(Owners.OWNERS.OWNER_EMAIL, owner.getOwnerEmail())
                .where(Owners.OWNERS.OWNER_ID.eq(ownerId))
                .returning()
                .fetchOne()
                .map(ownerConverter);
    }

    @Override
    public Integer delete(UUID ownerId) {

        return dslContext.delete(Owners.OWNERS)
                .where(Owners.OWNERS.OWNER_ID.eq(ownerId))
                .execute();
    }
}

转换器只是一个将记录转换为模型的组件:

package com.data.platform.core.converters;

import com.data.platform.core.entity.operation.tables.records.OwnersRecord;
import com.data.platform.core.models.Owner;
import org.jetbrains.annotations.Nullable;
import org.jooq.Record;
import org.jooq.RecordMapper;
import org.springframework.stereotype.Component;

import java.time.ZoneId;
import java.util.Date;
import java.util.Objects;
import java.util.function.Function;

@Component
public class OwnerConverter implements Function<OwnersRecord, Owner>, RecordMapper<Record, Owner> {
    /**
     * Applies this function to the given argument.
     *
     * @param ownersRecord the function argument
     * @return the function result
     */
    @Override
    public Owner apply(OwnersRecord ownersRecord) {
        return new Owner(ownersRecord.getOwnerId(), ownersRecord.getOwnerName(), ownersRecord.getOwnerEmail(), createdAtDate, updateAtDate);
    }

    /**
     * Map a r into a POJO.
     *
     * @param r The record to be mapped. This is never null.
     * @return The mapped value, which may be <code>null</code> in some
     * implementations.
     */
    @Override
    public @Nullable Owner map(Record r) {
        return apply((OwnersRecord) r);
    }
}

现在对于我遇到麻烦的测试部分,首先有一个抽象类,它应该会创建一个测试容器并创建一个DSLContext的示例,这样我们就可以测试仓库,如果我删除@SpringBootApplication(exclude = {R2dbcAutoConfiguration.class}),则org.springframework.beans.factory.UnsatisfiedDependencyException出现在抽象类上:

package com.data.platform.core.repository.common;

import org.jooq.DSLContext;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration;
import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.testcontainers.containers.PostgreSQLContainer;

import static com.data.platform.core.entity.operation.tables.Owners.OWNERS;

@RunWith(SpringRunner.class)
@ContextConfiguration(initializers = BaseRepositoryTest.Initializer.class)
@SpringBootApplication(exclude = {R2dbcAutoConfiguration.class})
public abstract class BaseRepositoryTest {
    public static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres")
            .withDatabaseName("data-platform")
            .withUsername("postgres")
            .withPassword("password");

    @Autowired
    DSLContext dslContext;

    static {
        postgres.start();
    }

    static class Initializer
            implements ApplicationContextInitializer<ConfigurableApplicationContext> {
        public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
            TestPropertyValues.of(
                            "spring.datasource.url=" + postgres.getJdbcUrl(),
                            "spring.datasource.username=" + postgres.getUsername(),
                            "spring.datasource.password=" + postgres.getPassword()
                    )
                    .applyTo(configurableApplicationContext.getEnvironment());
        }
    }

    public void cleanUpAll() {
        // There are more clean ups
        ownerCleanUp();
    }

    void ownerCleanUp() {
        dslContext.deleteFrom(OWNERS)
                .execute();
    }

}

并且有相应的OwnerRepositoryTest类,它从BaseRepository扩展,所以理论上它会有dslContext,但由于某种原因,给了我以下错误org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.bees.data.platform.core.repository.OwnerRepositoryTest': Unsatisfied dependency expressed through field 'dslContext'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.jooq.DSLContext' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

package com.data.platform.core.repository;

import com.data.platform.core.converters.OwnerConverter;
import com.data.platform.core.repository.common.BaseRepositoryTest;
import com.data.platform.core.entity.operation.tables.records.DomainsRecord;
import com.data.platform.core.models.Owner;
import org.jooq.Result;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

import static com.data.platform.core.repository.fixtures.OwnerRepositoryTestFixture.defaultListOfOwners;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

public class OwnerRepositoryTest extends BaseRepositoryTest {

    @Autowired
    OwnerRepository ownerRepository;

    @Autowired
    OwnerConverter ownerConverter;

    @Test
    public void testFindAll() {
        // Arrange
        Integer size = 10;
        Integer offset = 0;

        List<Owner> expectedOwners = defaultListOfOwners();

        // Act
        List<Owner> actualOwners = ownerRepository.findAll(size, offset);

        // Assert
        assertThat(expectedOwners, is(equalTo(actualOwners)));
    }
}

同样,由于我没有太多的经验与JOOQ我不能找到问题,或者如果有一个更好的方法来实现这种测试,任何形式的帮助将不胜感激。

hgqdbh6s

hgqdbh6s1#

我认为排除是故意添加的,你不能删除它。

@SpringBootApplication(exclude = {R2dbcAutoConfiguration.class})

如果你遇到了这篇老文章中提到的问题。这可能对你有帮助jooq-dslcontex

相关问题