Spring @Autowired字段 - 访问修饰符,私有或包私有?

vik*_*eve 16 java spring unit-testing private access-modifiers

假设我们@Autowired在类中的各个字段上使用注释,并且我们没有编写也可以设置字段的setter或构造函数.

问题 - 访问修饰符应该是什么,private或者package-private(即没有)?

例如:

public class MyClass {
    @Autowired
    private MyService myService;
}
Run Code Online (Sandbox Code Playgroud)

VS

public class MyClass {
    @Autowired
    MyService myService;
}
Run Code Online (Sandbox Code Playgroud)

在第一种情况下(private字段)Spring使用反射来连接字段,即使它没有setter.

第二种情况(package-private字段)允许我们能够访问这些字段(例如,设置模拟),如果我们需要扩展类以进行测试.

所以这两种情况都很好,但更值得推荐,特别是在测试方面?

Sim*_*ven 6

第一种情况还允许您根据框架注入模拟.例如,使用@InjectMocksMockito 的注释.你也有ReflectionTestUtils.setFieldSpring测试,......

我个人并不太喜欢为测试目的过多地修改类,所以我会选择第一种情况.但在一天结束时,这主要取决于您首选的测试框架.

  • 为什么不将 HTTPS 调用的责任放在可以在测试中模拟的外部注入组件?您还可以使用 Spy 或部分 Mockito 模拟来“覆盖”此方法,而无需创建显式子类。 (2认同)

trf*_*trf 6

我通常更喜欢将字段设为私有并使用setter注入:

public class MyClass {

    private MyService myService;

    @Autowired
    public void setMyService(MyService myService) {
        this.myService = myService;
    }
}   
Run Code Online (Sandbox Code Playgroud)

允许服务为@Autowired,但使用模拟实例进行单元测试.


Deb*_*kia 6

所以这两种情况都很好,但更值得推荐,特别是在测试方面?

我认为属性应该是private:

@Autowired
private MyService myService;
Run Code Online (Sandbox Code Playgroud)

因为使用getter方法提供对属性的访问而不是允许其他类直接访问它们总是好的.

而对于测试的目的,注射mocksprivate properties工作方式将作为的相同package-private特性.

例如,Mockito你可以注入的模拟private MyServiceMyClass就象这样:

public class MyClassTest {

    @Mock
    MyService service;

    @InjectMocks
    MyClass serv = new MyClass();

    @Before
    public void init() {
    MockitoAnnotations.initMocks(this);
    }
}
Run Code Online (Sandbox Code Playgroud)