簡體   English   中英

如何模擬同一個類從Spring的method1調用的method2?

[英]How to mock method2 called from method1 from same class wtih Spring?

我有一個具有此體系結構的spring-boot應用程序:

@Controller > @Service > @Component

這是我的組件:

@Component
public class myComponent {

    @Autowired
    private ObjectMapper mapper;
    //com.fasterxml.jackson.databind.ObjectMapper

    @Autowired
    private Component2 component2;
    // some 3rd part REST service

    @Autowired
    private Component3 component3;
    //database access

    @Transactional(propagation = Propagation.REQUIRED)
    public List<SomePOJO> method1(String otherString) {
        String newOne = myString + otherString; //more logic here, but without components
        return this.method2(newOne);
    }

    public List<SomePojo> method2(String newOne){
        String one = component3.methodX(newOne); //access database with component3
        return component2.methodY(one); //more logic here, including component2 and mapper!
    }

}

使用Mockito我在測試類中實現了這一點:

@MockBean
public myComponent component;

@Before
public void before() throws Exception {
    MockitoAnnotations.initMocks(this);
    List<POJO> someList = new ArrayList<>(); //list populated with some specific POJO's
    Mockito.when(component.method1("specificString")).
        thenReturn(someList);
}

@Test
public void recuperaDados() throws Exception  {
    String response = given().authentication().preemptive().oauth2("loginInfo")
            .get("myComponent_method1_path/" + "specificString1").asString();
    //this specificString1 leads to myComponent.method1("specificString"), satisfying Mockito 
}

至此,我成功地完成了測試。 但是當我使用

Mockito.when(component.method2("specificString2")).thenReturn(someList);

接着

String response1 = given().authentication().preemptive().oauth2("loginInfo")
            .get("myComponent_method1_path/" + "specificString1").asString();
// this specificString1 leads to myComponent.method2("specificString2"), also satisfying Mockito
String response2 = component.method2("specificString2");
String response3 = component.method2("randomString");

response1為"" ,response2為someList正確字符串化,response3為null response2response3是預期的。 但我期望response1與response2相同或至少為null 我該如何正確模擬在同一個類中被另一個調用的方法並測試另一個?

編輯

我的測試課擴展了該課:

@ActiveProfiles("test")
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT)
public abstract class AbstractRestTest {

    @Autowired
    private WebApplicationContext wac;

    protected Dsl dsl = Dsl.getInstance();

    @Before
    public void globalSetup() {
        RestAssuredMockMvc.webAppContextSetup(wac);
    }

}

Mockito通過代理您希望存根的對象來工作,因此,除非在進行模擬的對象上調用方法,否則您的實現代碼將永遠不會執行。 因此,通過在模擬對象上調用method1,將永遠不會調用method2作為結果。

但是,有一種方法可以通過部分嘲諷來實現所需的效果。 在要測試method2的測試中,可以指示應執行真實的method1:

when(component.method1("specificString")).thenCallRealMethod();

應該注意的是,mockito 文檔指出使用部分模擬可能表示代碼異味。 因此,問題是,method2是否真的必須公開? 如果它只是公開的,因為您希望模擬它的實現,那么這是一個錯誤。 使用模擬,您只希望存根對象的公共api。 任何私有方法或輔助方法都應視為內部方法,應忽略。 如果您在測試該對象的地方也是如此,則僅應測試公共方法,而間接測試幫助程序方法。

沒錯,第一個結果為空字符串而不是null是奇數。 我認為這可能與某些未提供的代碼有關,例如控制器或服務。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM