【问题标题】:How can I mock an autowired instance in an abstract test class?如何在抽象测试类中模拟自动装配的实例?
【发布时间】:2020-04-11 06:22:32
【问题描述】:

我有一个抽象服务类,它自动装配指定类型的存储库。

abstract class SomeService<T extends SomeRepository<U>, U ...> {

    @Autowrired
    @Accessors(fluent = true)
    @Getter(PROTECTED)
    private U repositoryInstance;
}

现在我正在尝试为服务类的子类创建一个抽象测试类。

@SpringBootTest
abstract class SomeServiceTest<T extends SomeService<U>, U extends SomeRepository<V>, V ...> {

    @Autowrired
    @Accessors(fluent = true)
    @Getter(PROTECTED)
    private T serviceInstance;

    // DOES NOT WORK!
    @MockBean
    @Accessors(fluent = true)
    @Getter(PROTECTED)
    private U repositoryInstance; // != serviceInstance.repositoryInstance();
}

但是在实际服务类的测试类中模拟 bean 是可行的。

class OtherServiceTest
        extends SomeServiceTest<OtherService, OtherRepository, ...> {

    @TestConfiguration
    OtherServiceTestConfiguration {

        // WORKS!!!
        // == serviceInstance().repositoryInstance();
        @MockBean private OtherRepository repositoryInstance;
    }
}

class AnotherServiceTest
        extends SomeServiceTest<AnotherService, AnotherRepository, ...> {

    // WORKS!!!
    // == serviceInstance().repositoryInstance();
    @MockBean private AnotherRepository repositoryInstance;
}

如何模拟 SomeServiceTest#repositoryInstance 以便它引用与 SomeServiceTest#serviceInstance.repositoryInstance() 相同的对象?

【问题讨论】:

    标签: java spring spring-boot mockito spring-boot-test


    【解决方案1】:

    我不知道@Autowire 是什么,因为我使用@Autowired。但是,据我所知,在对象声明中使用 autowire 是一种不好的做法。

    代替:

    @Autowired
    MyObject myObject;
    

    在构造函数中使用它:

    Repository repository;    
    
    @Autowired
    public SomeService(Repository repository) {
        this.repository = repository;
    }
    

    而且,在你的测试中:

    class SomeServiceTest {
    
        @Mock
        private Repository repositoryMock;
    
        private Service serviceUnderTest;
    
        @Before
        public void init() {
             MockitoAnnotations.initMocks(this);
             serviceUnderTest = new Service(repositoryMock);
        }
    

    【讨论】:

      【解决方案2】:

      你总是可以声明一个默认的和一个全参数的构造函数。 DI 框架将通过第一个实例化,注入自动装配的字段,而您可以使用测试类中的全参数实例化一个,将模拟对象作为构造函数参数传递。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-01-24
        • 1970-01-01
        • 2020-01-01
        • 1970-01-01
        • 2019-02-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多