java - 如何从非模拟方法中获取结果?

标签 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")
                    )))));
}

有 2 个模拟方法(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 并将 stub 更改为:

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

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

好的,现在的问题是在调用 findCompaniesToSelect() 方法时调用了 companyRepository.findAll 方法。我想从测试中调用模拟的 findAll 方法来获取模拟公司而不是真实公司。

编辑 2:

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

最佳答案

如果你想在一个对象上结合模拟方法和真实方法调用,那么你需要使用 spy 而不是模拟。

@Spy
CompanyService companyServiceSpy

不过,您需要以不同方式 stub 您的模拟方法。使用 doReturn(...).when(...) 而不是您当前使用的 stub 。

看看http://www.baeldung.com/mockito-spy有关使用 spy 的更多信息。

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

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 引导如何设置测试。

关于java - 如何从非模拟方法中获取结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45818637/

相关文章:

java - HornetQ 独立运行并编写客户端代码

java - 严重: java. sql.SQLException:字段 'columnname'没有默认值

java - groovy spock 测试无法在同一包中找到 java 类

java - 检索 session token

java - Spring Security OAuth2 - 是否可以更改表和列名称?

java - 使用 Spring Security 的 SiteMinder 注销

从 OS X 以外的环境驱动的 iOS UI 测试

java - 加载 ApplicationContext 失败 Spring java.lang.NoClassDefFoundError

testing - 哪个自动化框架提供了一个选项来安排运行?

python - 测试 Django 和 Celery