如果在我们测试的方法中声明了新的关键字,我们可以对实例进行模拟吗?

问题描述 投票:0回答:1

我是Mockito和Junit的新手,我正在使用Spring Boot。

我想知道的是,如果这个实例在我们测试的方法中声明了一个新的关键字,我们是否可以对它进行模拟?

比如说

@Service 
class A {

    @Autowired
    X x;

    @Autowired
    Y y;

    public void testMe(){
        imCommunicatingWithSomeRestClient();
    }

    private void imCommunicatingWithSomeRestClient(){
        String body="";
        MyRestClient client=new MyRestClient(iTakeUrlNeedsToHit); //no arg constructor not exist and suppose this is the method of some Core jar project
        client.callDataRest(HTTP.GET,body)
    }

}

虽然我想模拟它,但我已经试过了所有的方法。@Spy @Mock, @InjectMocks 来检查它是否会有不同的行为,但这些对我来说都不起作用,因为它总是创建一个新的对象并调用真正的方法。

所以我稍微改变了一下方法,使用了 BeanFactory 而不是新的,我把它替换成:

MyRestClient client=beanFactory.getBean(MyRestClient.class,jobDataRestUrl); 

所以我有这些问题。

  1. 上面已经问过了(如果我们模拟实例,如果它用new关键字声明,那就在我们测试的方法里面)。

  2. 如果我当前的项目是 弹簧靴 计划和 MyRestClient 是在核心编写的jar里面。标准是不是说我不应该用Bean Factory来创建它,因为我认为我应该用这种方式来创建它,让Spring来处理它。

  3. 我甚至尝试过使用反射,但似乎它也不能在方法中使用new关键字创建的实例,而不是在类的层面。

spring-boot junit mockito powermockito
1个回答
1
投票

你目前的设置并不能有效地进行测试。你可能还是会用很多奇怪的变通方法来做,但还是不推荐。下面是你可以做的,首先,你的类里面不应该有任何形式的依赖初始化(比如说像 new MyRestClient(...)). 因此,将REST客户端移动到属性级别,并通过构造函数注入。

@Service
class A {
    private final X x;
    private final Y y;
    private final MyRestClient restClient;

    public A (X x, Y y, MyRestClient restClient) {
        this.x = x;
        this.y = y;
        this.restClient = restClient;
    }

    public void testMe() {
        imCommunicatingWithSomeRestClient();
    }

    private void imCommunicatingWithSomeRestClient() {
        String body = "";
        restClient.callDataRest(GET, body);
    }
}

由于您使用的是Spring,您可以创建一个REST客户端的Bean,并将端点URL移动到一个外部属性。

class Config {

    @Bean
    public MyRestClient myRestClient(@Value("${property.name}") String url) {
        return new MyRestClient(url);
    }

}

最后,你可以轻松地模拟该REST客户端的行为。

@ExtendWith(MockitoExtension.class)
class TestA {

    @Mock
    private X x;

    @Mock
    private Y y;

    @Mock
    private MyRestClient restClient;

    @InjectMocks
    private A a;

    // your tests...
}
© www.soinside.com 2019 - 2024. All rights reserved.