java Junit:为删除实体的方法编写测试?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38081611/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 03:05:46  来源:igfitidea点击:

Junit: writing a test for a method that deletes an entity?

javahibernatejpajunitspring-data

提问by java123999

What would be the most exhaustivetests that I could write for the following piece of code?

我可以为以下代码编写的最详尽的测试是什么?

public void deleteFromPerson(person person) {
    person = personRepository.returnPerson(person.getId());
    personRepository.delete(person);
}

This method is within a serviceclass. The method makes calls to a JpaRepositorythat then calls it's delete()method on the entity.

这个方法在a service类中。该方法调用JpaRepository,然后delete()在实体上调用它的方法。

If it is not possible to test if the entity is being deleted, is there any othertests casesI can run on the method?

如果无法测试实体是否被删除,是否还有其他tests cases方法可以在该方法上运行?

回答by Compass

There are two testing strategies. One is unit testing, i.e. making sure your service works. The other is integration/end-to-end testing, i.e. making sure everything plays nicely together.

有两种测试策略。一种是单元测试,即确保您的服务有效。另一个是集成/端到端测试,即确保一切都很好地协同工作。

You unit test stuff you own, you integration test everything you have. This is a pretty rough example using just your statement, plus some made up stuff where I can't fill in the blanks.

你单元测试你拥有的东西,你集成测试你拥有的一切。这是一个非常粗略的例子,只使用你的陈述,加上一些我无法填空的东西。

Unit Tests

单元测试

Using Mockito

使用 Mockito

PersonRepository personRepository = mock(PersonRepository.class);

@TestSubject
PersonService personService = new PersonService(): 

@Test
public void unitTest() {
    personService.setPersonRepository(personRepository);
    Person person = new Person(1L);
    Person person2 = new Person(1L);

    when(personRepository.returnPerson(1L)).thenReturn(person2); //expect a fetch, return a "fetched" person;

    personService.deleteFromPerson(person);

    verify(personRepository, times(1)).delete(person2); //pretty sure it is verify after call
}

Using EasyMock...

使用 EasyMock...

@Mock
PersonRepository personRepository; //assuming it is autowired

@TestSubject
PersonService personService = new PersonService(): 

@Test
public void unitTest() {
    Person person = new Person(1L);
    Person person2 = new Person(1L);

    EasyMock.expect(personRepository.returnPerson(1L)).andReturn(person2); //expect a fetch, return a "fetched" person;
    personRepository.delete(person2);
    EasyMock.expectLastCall(); //expect a delete for person2 we plan to delete
    replayAll();

    personService.deleteFromPerson(person);

    verifyAll(); //make sure everything was called
}

Yes, this test looks like it is written rigidly, but that's really all you're testing in the unit test, anyways. You want the DB to fetch a Person from the database using an argument, hence why there are two Personobjects, and you expect to delete that passed Personobject, which is why you expect the call. Simple method yields simple test. You basically want to ensure you're interacting with your repository as you expect. Repository could be broken or null in actual implementation, but that doesn't change the fact that your service is implemented correctly.

是的,这个测试看起来写得很死板,但无论如何,这就是您在单元测试中测试的全部内容。您希望 DB 使用参数从数据库中获取 Person,因此为什么有两个Person对象,并且您希望删除该传递的Person对象,这就是您希望调用的原因。简单的方法产生简单的测试。您基本上希望确保您按预期与存储库进行交互。存储库在实际实现中可能会被破坏或为空,但这不会改变您的服务已正确实现的事实。

Integration Tests

集成测试

On the other hand, if you want to do an integration test, no mocking is used. Instead, you'll need to wire up everything like a test DBand repo. I'll leave that up to you since there's no reference for implementation.

另一方面,如果您想进行集成测试,则不使用模拟。相反,您需要像测试数据库和存储库一样连接所有东西。我将把它留给你,因为没有实施参考。

@Test
public void integrationTestForAddAndDelete() {
    Person person = createDummyPersonForInsertion(); //static method that creates a test Person for you
    Person comparePerson;
    //make sure we haven't added the person yet
    Assert.assertNull(personService.getPerson(person));

    //add the Person
    comparePerson = personService.addPerson(person);
    Assert.assertNotNull(personService.getPerson(person));
    //add a rigorous compare method to make sure contents are the same, i.e. nothing is lost or transmuted incorrectly, ignoring ID if that is autogen
    //alternatively, you can create a unit test just for Person
    Assert.assertEquals(person, comparePerson); 

    //remove the Person
    personService.deleteFromPerson(person);
    Assert.assertNull(personService.getPerson(person));

    //test for exception handling when you try to remove a non-existent person;
    personService.deleteFromPerson(person);

    //test for exception handling when you try to remove null
    personService.deleteFromPerson(null);
}

In this case, you want to make sure your repo actually handles all the calls from the service. You know your service works from the unit test, but does the repo work from the service or have you configured something wrong

在这种情况下,您要确保您的存储库实际处理来自服务的所有调用。您知道您的服务可以从单元测试中运行,但是 repo 是否可以从服务中运行,或者您是否配置了错误