I am trying to test supplierService class and getting NoSuchElementException while testing getSKUNameTest()
java.util.NoSuchElementException: No value present at java.util.Optional.get(Optional.java:135) at com.inventory.SpringInventory1ApplicationTests.getSKUNameTest(SpringInventory1ApplicationTests.java:66) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:686) at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131) at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149) at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140) at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84) at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115) at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105) at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37) at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104) at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:212) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:208) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:137) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:71) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) at java.util.ArrayList.forEach(ArrayList.java:1259) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) at java.util.ArrayList.forEach(ArrayList.java:1259) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229) at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197) at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:137) at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:89) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)
Catalog.java and Supplier.java are the entity class
Catalog.java
package com.inventory.entities; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.MapsId; import javax.persistence.OneToOne; import javax.persistence.Table; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonManagedReference; @Entity @Table(name = "catalog") public class Catalog { @Id @Column(length = 50) // @GeneratedValue private int skuCode; @Column(length = 50) private String skuName; @Column(length = 50) private String skuDesc; @Column(length = 50) private String bName; @Column(length = 50) private String bDesc; @OneToOne(cascade = CascadeType.ALL) @JoinColumn(name = "supplier_id", nullable = false, unique = true) @JsonManagedReference @JsonIgnore private Supplier supplier;// FK public Catalog() { } public Catalog(int skuCode, String skuName, String skuDesc, String bName, String bDesc, Supplier supplier) { this.skuCode = skuCode; this.skuName = skuName; this.skuDesc = skuDesc; this.bName = bName; this.bDesc = bDesc; this.supplier = supplier; } public int getSkuCode() { return skuCode; } public void setSkuCode(int skuCode) { this.skuCode = skuCode; } public String getSkuName() { return skuName; } public void setSkuName(String skuName) { this.skuName = skuName; } public String getSkuDesc() { return skuDesc; } public void setSkuDesc(String skuDesc) { this.skuDesc = skuDesc; } public String getbName() { return bName; } public void setbName(String bName) { this.bName = bName; } public String getbDesc() { return bDesc; } public void setbDesc(String bDesc) { this.bDesc = bDesc; } public Supplier getSupplier() { return supplier; } public void setSupplier(Supplier supplier) { this.supplier = supplier; } @Override public String toString() { return "Catalog [skuCode=" + skuCode + ", skuName=" + skuName + ", skuDesc=" + skuDesc + ", bName=" + bName + ", bDesc=" + bDesc + ", supplier=" + supplier + "]"; } }
Supplier.java
package com.inventory.entities; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.OneToOne; import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.Table; import com.fasterxml.jackson.annotation.JsonBackReference; @Entity @Table(name = "supplier") public class Supplier { @Id @Column(length = 50) private int supplierId; @Column(length = 50) private String supplierName; @OneToOne(mappedBy = "supplier",fetch = FetchType.LAZY) @JsonBackReference private Catalog catalog; public Supplier() { } public Supplier(int supplierId, String supplierName) { super(); this.supplierId = supplierId; this.supplierName = supplierName; } public int getSupplierId() { return supplierId; } public void setSupplierId(int supplierId) { this.supplierId = supplierId; } public String getSupplierName() { return supplierName; } public void setSupplierName(String supplierName) { this.supplierName = supplierName; } public Catalog getCatalog() { return catalog; } public void setCatalog(Catalog catalog) { this.catalog = catalog; } @Override public String toString() { return "Supplier [supplierId=" + supplierId + ", supplierName=" + supplierName + ", catalog=" + catalog + "]"; } }
Service Classes
CatalogService.java
package com.inventory.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.inventory.entities.Catalog; import com.inventory.repository.CatalogRepository; @Service public class CatalogService { @Autowired private CatalogRepository catalogRepository; public Catalog getCatalogById(int id) { return catalogRepository.findById(id).get(); } public Catalog saveCatalog(Catalog catalog) { return catalogRepository.save(catalog); } }
SupplierService.java
package com.inventory.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.inventory.entities.Supplier; import com.inventory.repository.SupplierRepository; @Service public class SupplierService { @Autowired private SupplierRepository supplierRepository; public Supplier getSupplierById(int id) { return supplierRepository.findById(id).get(); } public Supplier insertSupplier(Supplier supplier) { return supplierRepository.save(supplier); } }
Repository Classes
SupplierRepository.java
package com.inventory.repository; import org.springframework.data.repository.CrudRepository; import com.inventory.entities.Supplier; public interface SupplierRepository extends CrudRepository<Supplier, Integer>{ }
CatalogRepository.java
package com.inventory.repository; import org.springframework.data.repository.CrudRepository; import com.inventory.entities.Catalog; public interface CatalogRepository extends CrudRepository<Catalog, Integer>{ }
Here is Testing Class
SpringInventory1ApplicationTests.java
package com.inventory; import static org.junit.Assert.assertNotNull; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.when; import java.util.Optional; import org.junit.Before; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.context.junit4.SpringRunner; import com.inventory.entities.Catalog; import com.inventory.entities.Supplier; import com.inventory.repository.CatalogRepository; import com.inventory.repository.SupplierRepository; import com.inventory.service.CatalogService; import com.inventory.service.SupplierService; @RunWith(SpringRunner.class) @SpringBootTest class SpringInventory1ApplicationTests { @Autowired private CatalogService catalogSevice; @InjectMocks private SupplierService supplierService; @MockBean private CatalogRepository catalogRepository; @Mock private SupplierRepository supplierRepository; @Before void setUp() { MockitoAnnotations.initMocks(this); } @Test public void getCatalogByIdTest() { Catalog catalog = new Catalog(201,"Kitchen Products", "Daily Products", "bajaj", "bajaj Eletronics", new Supplier(1,"Shubham")); when(catalogRepository.findById(201)).thenReturn(Optional.of(catalog)); assertEquals(catalog,catalogSevice.getCatalogById(201)); } @Test public void getSKUNameTest() { Supplier supplier = new Supplier(1,"John"); Catalog catalog = new Catalog(); catalog.setbName("Bajaj"); catalog.setbDesc("Eletrical gadgets"); catalog.setSkuCode(101); catalog.setSkuName("Mixer"); catalog.setSupplier(supplier); //supplier.setCatalog(catalog); when(supplierRepository.findById(1).get()).thenReturn(supplier); Supplier s = supplierService.getSupplierById(1); assertEquals("Mixer",supplierService.getSupplierById(1).getCatalog().getSkuName()); } @Test public void insetCatalogTest() { Catalog catalog = new Catalog(201,"Kitchen Products", "Daily Products", "bajaj", "bajaj Eletronics", new Supplier(6,"Shubham")); when(catalogRepository.save(catalog)).thenReturn(catalog); assertEquals(catalog, catalogSevice.saveCatalog(catalog)); } @Test public void insertSupplierTest() { Supplier supplier = new Supplier(20, "Shubhanjali"); when(supplierRepository.save(supplier)).thenReturn(supplier); assertEquals(supplier, supplierService.insertSupplier(supplier)); } }
I am getting NoSuchElementException in testing getSKUNameTest().
while debugging I noticed that when(supplierRepository.findById(1).get()).thenReturn(supplier);
this line is returning nothing, but I don’t know how to resolve this issue, Please Help.
Please help me as I am new to Spring and Hibernate as well in stackoverflow if anything needs to be edited or question is not clear please guide me so I can improve it further.
Advertisement
Answer
You stub the call in the wrong way.
when(supplierRepository.findById(1).get()).thenReturn(supplier);
Refactor to:
when(supplierRepository.findById(1)).thenReturn(Optional.of(supplier));
When you have a chain of calls, you need to stub each consecutive call one by one (assuming all objects returned in the interim are mocks).
Here, I take advantage of the fact that Optional is a simple object which is easy to construct, there is no additional value of mocking it.
On top of that:
- Test one object at a time. Here you test
catalogSevice
andsupplierService
. Separate these tests. - Your annotations are a mess. Both objects under test are initialized in a different way. Either use Mockito annotations (@Mock, @InjectMocks, MockitoAnnotations.initMocks or Mockito runner) or use Spring ones (@SpringBootTest, @MockBean, @Autowired). In particular, @Mock fields are not injected into your Spring context. In this case I advise going the former way – spring tests tend to create more beans and take longer to execute.