我从1.X迁移到Spring 2.X,发生了一些错误。我不能处理这个。
(下面编辑)
我同时尝试了when...
和doReturn
,但这些方法均无效。
我要进行单元测试的方法:
@Service
public class BookRentalService {
private final AccountRepository accountRepository;
private final BookRepository bookRepository;
private final BookRentalsRepository bookRentalsRepository;
@Autowired
public BookRentalService(BookRepository bookRepository, BookRentalsRepository bookRentalsRepository, AccountRepository accountRepository) {
this.bookRepository = bookRepository;
this.bookRentalsRepository = bookRentalsRepository;
this.accountRepository = accountRepository;
}
public String rentBook(int accountID, int bookID) {
Account account = accountRepository.findById(accountID)
.orElseThrow(() -> new IllegalArgumentException("Account does not exist!"));
if (account.getAmountOfCashToPay() == 0) {
if (bookRepository.doesBookExistsWithGivenID(bookID)) {
Book bookToRent = bookRepository.findById(bookID)
.orElseThrow(() -> new IllegalArgumentException("Book does not exist!"));
if (bookToRent.isAvailable()) {
updateBookAvailabilityAndSaveToDb(bookToRent);
BookRentals preparedBookToRent = prepareBookToRent(accountID, bookToRent);
bookRentalsRepository.save(preparedBookToRent);
} else {
throw new IllegalArgumentException("Book is not available");
}
}
} else {
throw new IllegalArgumentException("Please go to paypenalty/accountID to settle the arrears, otherwise you can not rent more books!");
}
return "Book was rented";
}
单元测试
@RunWith(MockitoJUnitRunner.class)
public class BookRentalServiceTest {
@Mock
public BookRentalsRepository bookRentalsRepository;
@Mock
public BookRepository bookRepository;
@Mock
public AccountRepository userRepository;
@InjectMocks
public BookRentalService bookRentalService;
@Test(expected = IllegalArgumentException.class)
public void rentBookWhenAccountNotExists() {
Book book = createDummyBook();
Account user = createDummyUser();
//when(bookRepository.doesBookExistsWithGivenID(book.getId())).thenReturn(true);
//when(bookRepository.findById(book.getId()).orElse(null)).thenReturn(book);
//when(userRepository.doesAccountExistsWithGivenID(user.getId())).thenReturn(false);
doReturn(book).when(bookRepository).findById(book.getId()).orElse(null);
doReturn(true).when(bookRepository).doesBookExistsWithGivenID(book.getId());
doReturn(false).when(userRepository).doesAccountExistsWithGivenID(user.getId());
String expected = "Account does not exist";
assertEquals(expected, bookRentalService.rentBook(user.getId(), book.getId()));
}
}
Stacktrace:
java.lang.Exception: Unexpected exception, expected<java.lang.IllegalArgumentException> but was<org.mockito.exceptions.misusing.WrongTypeOfReturnValue>
at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:28)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79)
at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85)
at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: org.mockito.exceptions.misusing.WrongTypeOfReturnValue:
Book cannot be returned by findById()
findById() should return Optional
***
If you're unsure why you're getting above error read on.
Due to the nature of the syntax above problem might occur because:
1. This exception *might* occur in wrongly written multi-threaded tests.
Please refer to Mockito FAQ on limitations of concurrency testing.
2. A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies -
- with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.
at bookrental.service.book.rentals.BookRentalServiceTest.rentBookWhenAccountNotExists(BookRentalServiceTest.java:71)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:19)
... 18 more
// EDIT 在蒂莫西的帮助下。代码看起来像这样。
@Test(expected = IllegalArgumentException.class)
public void rentBookWhenAccountNotExists() {
Book book = createDummyBook();
Account user = createDummyUser();
when(bookRepository.doesBookExistsWithGivenID(book.getId())).thenReturn(true);
when(bookRepository.findById(book.getId()).orElse(null)).thenReturn(book);
when(userRepository.doesAccountExistsWithGivenID(user.getId())).thenReturn(false);
//doReturn(book).when(bookRepository).findById(book.getId()).orElse(null);
//doReturn(true).when(bookRepository).doesBookExistsWithGivenID(book.getId());
// doReturn(false).when(userRepository).doesAccountExistsWithGivenID(user.getId());
bookRentalService.rentBook(user.getId(), book.getId());
}
和堆栈:
java.lang.Exception: Unexpected exception, expected<java.lang.IllegalArgumentException> but was<org.mockito.exceptions.misusing.WrongTypeOfReturnValue>
at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:28)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79)
at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85)
at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: org.mockito.exceptions.misusing.WrongTypeOfReturnValue:
Book cannot be returned by findById()
findById() should return Optional
***
If you're unsure why you're getting above error read on.
Due to the nature of the syntax above problem might occur because:
1. This exception *might* occur in wrongly written multi-threaded tests.
Please refer to Mockito FAQ on limitations of concurrency testing.
2. A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies -
- with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.
at bookrental.service.book.rentals.BookRentalServiceTest.rentBookWhenBookNotExist(BookRentalServiceTest.java:53)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:19)
... 18 more
答案 0 :(得分:0)
此行是错误的:
when(booRepository.findById(book.getId())).thenReturn(Optional.of(book));
orElse()不是模拟对象上的方法,而是属于Optional ...的方法。该行应为:
{{1}}