如何从非模拟方法获得结果?

时间:2017-08-22 13:11:59

标签: java spring testing mocking mockito

我从使用未被模拟的方法获取结果时遇到问题。我不想模仿结果,但要从这个方法中获得真正的结果。该方法适用于应用程序,因此这不是问题。我有一个测试:

    @Test
public void shouldGetCompaniesToSelect() throws Exception {
    Company company = new Company("company", new Address());
    Company relatedCompany1 = new Company("relatedCompanyName1", new Address());
    Company notRelatedCompany = new Company("notRelatedCompanyName", new Address());
    Company relatedCompany2 = new Company("relatedCompanyName2", new Address());
    CompanyRelation companyRelation1 = new CompanyRelation(relatedCompany1);
    CompanyRelation companyRelation2 = new CompanyRelation(relatedCompany2);
    company.getCompanyRelations().add(companyRelation1);
    company.getCompanyRelations().add(companyRelation2);

    when(companyServiceMock.findAll()).thenReturn(Arrays.asList
            (company, relatedCompany1, notRelatedCompany, relatedCompany2));
    when(companyServiceMock.findOne(1L)).thenReturn(company);

    List<Company> companiesToSelect =  companyServiceMock.findCompaniesToSelect(company);

    mockMvc.perform(get("/company/1"))
            .andExpect(model().attribute("companiesToSelect", hasSize(1)))
            .andExpect(model().attribute("companiesToSelect", hasItem(
                    hasProperty("relatedCompany", hasProperty(
                            "name", is("notRelatedCompanyName")
                    )))));
}

有两个模拟方法(findAll和findOne)然后我想执行方法并从findCompaniesToSelect(公司 - 这是为测试创建的对象)获得实际结果。 companiesToSelect的大小应为1,但它返回0.

findCompaniesToSelect方法:

public List<Company> findCompaniesToSelect(Company company) {
    List<Company> companiesToSelect = companyRepository.findAll();
    for (CompanyRelation companyRelation :
            company.getCompanyRelations()) {
        companiesToSelect.remove(companyRelation.getRelatedCompany());
    }
    companiesToSelect.remove(company);
    return companiesToSelect;
}

我该怎么做?

编辑1:

好的,我已将其更改为@Spy并将存根更改为:

    Mockito.doReturn(Arrays.asList(company, relatedCompany1, 
    notRelatedCompany, relatedCompany2)).when(companyServiceMock).findAll();
    Mockito.doReturn(company).when(companyServiceMock).findOne(1L);

但是当我运行测试时,findCompaniesToSelect()方法使用真实公司而不是模拟公司。

好的,现在问题是当调用findCompaniesToSelect()方法时,调用companyRepository.findAll方法。我想从测试中调用mocked findAll方法来获得被嘲笑的公司而不是真正的公司。

编辑2:

好的,问题是因为findCompaniesToSelect()方法使用的是存储库,而不是服务。 :d

2 个答案:

答案 0 :(得分:2)

如果你想在对象上使用模拟方法和实际方法调用的组合,那么你需要使用间谍而不是模拟。

@Spy
CompanyService companyServiceSpy

您需要以不同方式存储模拟方法。使用doReturn(...)。when(...)而不是你当前正在使用的存根。

有关使用间谍的更多信息,请查看http://www.baeldung.com/mockito-spy

编辑:由于您在测试中模拟某些行为,因此您应该为MockMvc对象使用独立设置,并将模拟注入控制器,如下所示:

MockMvc mockMvc;

@Spy
CompanyService companyServiceSpy;

@InjectMocks
CompanyController companyController;

@Before
public void setup() {
    MockitoAnnotations.initMocks(this);
    mockMvc = MockMvcBuilders.standaloneSetup(companyController).build();
}

编辑2:您也可以通过在当前设置中将@Spy更改为@SpyBean来解决此问题。不是100%肯定,因为我并不完全熟悉Spring启动如何设置测试。

答案 1 :(得分:0)

这种情况正在发生,因为您的服务类即companyService被模拟。 我建议使用 Restassured 来测试您的Restservice,它不需要为RestService组件的不同方法创建模拟,即您不需要模拟CompanyService。

进一步阅读:

RestAssured

Example Code for RestAssured testing