可以在带有@Autowired构造函数的原型bean中注入模拟对象吗?

huangapple go评论76阅读模式
英文:

Can I inject mocks into a prototype bean with Autowired constructor?

问题

@Component
@Scope(value = "prototype")
public class Prototype {

    private DependantService dependantService;

    @Autowired
    public Prototype(DependantService dependantService) {
        this.dependantService = dependantService;
    }
}
@SpringBootTest
public class TestPrototype {

    @Autowired
    private ApplicationContext ctx;

    @Mock
    private DependantService dependantService;

    @Test
    public void testPrototype() {
        // How can I inject the mock service?
        ctx.getBean(Prototype.class);
    }
}
英文:

Is it possible to inject a mock service into a prototype bean using the @Autowired constructor? I realize I could switch to setter injection but I would prefer to use the constructor if possible.

@Component
@Scope(value = "prototype")
public class Prototype {

    private DependantService dependantService;

    @Autowired
    public Prototype(DependantService dependantService) {
        this.dependantService = dependantService;
    }
}
@SpringBootTest
public class TestPrototype {

    @Autowired
    private ApplicationContext ctx;

    @Mock
    private DependantService dependantService;

    @Test
    public void testPrototype() {
        // How can I inject the mock service?
        ctx.getBean(Prototype.class);
    }
}

答案1

得分: 0

原来 getBean 方法有一个可以接受参数的重载版本。如果可以的话,我会给自己的问题投反对票。

@SpringBootTest
public class TestPrototype {

    @Autowired
    private ApplicationContext ctx;

    @Mock
    private DependantService dependantService;

    @Test
    public void testPrototype() {
        Prototype p = ctx.getBean(Prototype.class, dependantService);
        // 测试 p
    }
}
英文:

Turns out there is an overloaded version of the getBean method that accepts arguments. I would downvote my on question if I could.

@SpringBootTest
public class TestPrototype {

    @Autowired
    private ApplicationContext ctx;

    @Mock
    private DependantService dependantService;

    @Test
    public void testPrototype() {
        Prototype p = ctx.getBean(Prototype.class, dependantService);
        // Test p
    }
}

</details>



# 答案2
**得分**: 0

```java
如果你想加速单元测试并且进行真正的隔离单元测试我建议看一下`@InjectMocks` Mockito注解。`@SpringBootTest`会启动相当繁琐的Spring容器

@Controller
public class MyController {
    @Inject
    private Logger log;

    public void methodThatNeedsTesting() {
        log.info("hey this was called");
    }
}
@TestInstance(Lifecycle.PER_CLASS)
@ExtendWith({ MockitoExtension.class })
class MyControllerTest {
    @Mock
    private Logger log;

    @InjectMocks
    private MyController myController;

    @Test
    void test_methodThatNeedsTesting() throws Exception {
        myController.methodThatNeedsTesting();
        // myController在上述代码中不会抛出NPE,因为log字段已经被注入为一个mock对象
    }
}
英文:

If you want to speed up your unit tests, [and do true isolated unit testing,] I suggest taking a look at the @InjectMocks mockito annotation. @SpringBootTest fires up the Spring container which is pretty cumbersome.

@Controller
public class MyController {
 @Inject
 private Logger log;


 public methodThatNeedsTesting(){
  log.info(&quot;hey this was called&quot;);
 }
}
@TestInstance(Lifecycle.PER_CLASS)
@ExtendWith({ MockitoExtension.class })
class MyControllerTest {
 @Mock
 private Logger log;

 @InjectMocks
 private MyController myController;
 
 @Test
 void test_methodThatNeedsTesting() throws Exception {
  myController.methodThatNeedsTesting();
  // myController will not throw an NPE above because the log field has been injected with a mock
 }

huangapple
  • 本文由 发表于 2020年8月22日 23:43:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/63538076.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定