gpt4 book ai didi

java - 使用 mongodb 存储库进行单元测试

转载 作者:可可西里 更新时间:2023-11-01 09:52:21 28 4
gpt4 key购买 nike

我已经构建了使用 MongoDB 的应用程序,但我遇到了测试问题。

只要我使用 JPA 和一些关系数据库,我就会使用一些测试层将持久性切换到内存数据库(linke HSQLDB 或 MySQL)以进行测试。这样我就能够限制 IO 操作并加快测试速度。但是,对于 MongoDB 和 Spring Data,使用基于扩展 MongoRepository 的接口(interface)的存储库非常方便。

我的问题是在使用存储库时如何处理单元测试和功能测试?例如,我有一个简单的类,它被标记为 mongo 文档:

public class Company {

@Id
private String id;
@NotEmpty
private String name;
private String description;
private String website;
private String logo;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

public String getWebsite() {
return website;
}

public void setWebsite(String website) {
this.website = website;
}

public String getLogo() {
return logo;
}

public void setLogo(String logo) {
this.logo = logo;
}
}

和相关的存储库:

@Repository
public interface CompanyRepository extends MongoRepository<Company, Serializable> {
}

在对应的 Controller 中使用:

@RestController
public class CompanyController {

private static final Logger log = LoggerFactory.getLogger(CompanyController.class);
@Autowired
private CompanyRepository repository;

@RequestMapping(value = "/company", method = RequestMethod.POST)
public void create(@Valid @RequestBody(required = true) Company company) {
repository.save(company);
}
}

最后我做了两个测试(但它可以是一个涵盖两个任务的测试),涵盖 Controller api 和数据格式(我模拟存储库以防止 IO 操作,它工作得很好),第二个我想确保传递的对象已成功保留。当它出来时,它并不是那么简单。首先(如果我错了请纠正我)没有内存中的 mongo 实现。其次,由于我想是继承,我无法用 mockito 执行 save 方法来验证。

@ContextConfiguration(classes = Application.class)
@WebAppConfiguration
public class CompanyControllerNGTest extends AbstractTestNGSpringContextTests {

@Mock
private CompanyRepository repositoryMock;
@Autowired
@InjectMocks
private CompanyController controller;
private MockMvc mockMvc;

@BeforeMethod
public void setUp() {
MockitoAnnotations.initMocks(this);
}

@DataProvider
public static Object[][] companyJsonProvider() {
return new Object[][]{
{Json.createObjectBuilder()
.add("name", "JakasFirma")
.add("description", "jakas firma opis")
.add("website", "www.jakasfirma.com")
.add("logo", "jakies logo")
.build(), status().isOk()},
{Json.createObjectBuilder()
.add("name", "JakasFirma")
.build(), status().isOk()},
{Json.createObjectBuilder()
.add("description", "jakas firma opis")
.add("website", "www.jakasfirma.com")
.add("logo", "jakies logo")
.build(), status().isBadRequest()},
{Json.createObjectBuilder()
.build(), status().isBadRequest()},
};
}

@Test(dataProvider = "companyJsonProvider", enabled = false)
public void apiTest(JsonObject companyJson, ResultMatcher expectedStatus) throws Exception {
//given
mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
String content = companyJson.toString();

//when
mockMvc.perform(post("/company").contentType(MediaType.APPLICATION_JSON).content(content)).
//then
andExpect(expectedStatus);

}

@Test
public void shouldCreate() throws Exception {
//given

//when
controller.create(mock(Company.class));

//then
//verify(repositoryMock, times(1)).save(any(Iterable.class));
}
}

我考虑过在 Controller 和存储库之间引入一个可以模拟和验证机器人的 dao 层,它增加了更多的复杂性和强制性来封装存储库使用的每个方法。它也没有解决问题,而是将其部分移至较低级别。有什么方法或做法可以帮助解决这类问题吗?或者我应该对 mongo 使用不同的方法?

最佳答案

对于单元测试,我会 stub 或编写 CompanyRepository 的实现并将其注入(inject)您的 Controller (您可能需要为 CompanyRepository 添加 Setter 方法)。

对于功能或集成测试,我会考虑使用以下方法

@ContextConfiguration("file:my-context-file.xml")
@RunWith(SpringJUnit4ClassRunner.class)

在上下文文件中,我希望您配置仅运行测试所需的 bean。

关于java - 使用 mongodb 存储库进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21522198/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com