0

I keep getting NullPointerException on all my Tests. I have a CashRegister Class with a Product object lastScannedProduct that is supposed to be initially null but then it's supposed to be changed I tried to change it by using a foreach loop that scans through a LinkedHashMap<Product, SalesRecord> salesCache that saves all the Products and Sales Records but it doesn't seem to work, I would grately appreciate any help:

class CashRegister {

    private final Clock clock;
    private final Printer printer;
    private final UI ui;
    private final SalesService salesService;

    // Declare a field to keep a salesCache, which is a mapping between a Product and a SalesRecord.
    // When a product gets scanned multiple times, the quantity of the salesRecord is increased. 
    // A LinkedHashMap has the benefit that, in contrast to the HashMap, the order in which 
    // the items were added is preserved.

    // Declare a field to keep track of the last scanned product, initially being null.

    // TODO Declare and initialize fields.
    Product lastScannedProduct = null;
    LinkedHashMap<Product, SalesRecord> salesCache;
    int quantity = 1;


    /**
     * Create a business object
     *
     * @param clock        wall clock
     * @param printer      to use
     * @param ui           to use
     * @param salesService to use
     */
    CashRegister(Clock clock, Printer printer, UI ui, SalesService salesService) {
        this.clock = clock;
        this.printer = printer;
        this.ui = ui;
        this.salesService = salesService;
        //lastScannedProduct = null;
        salesCache = new LinkedHashMap<>();

    }

    /**
     * The scan method is triggered by scanning a product by the cashier.
     * Get the product from the salesService. If the product can't be found, an UnknownProductException is thrown and the
     * error message from the exception is shown on the display (ui).
     * If found, check if there is a salesRecord for this product already. If not, create one. If it exists, update the quantity.
     * In case a perishable product was scanned, the cashier should get a calendar on his/her display.
     * The product is displayed on the display.
     *
     * @param barcode
     */
    public void scan(int barcode) {
        //TODO implement scan
        //Product product = salesService.lookupProduct(barcode);

        if (salesCache.containsKey(barcode)) { //TODO get the existing Sales Record and change quantity
            SalesRecord existing = new SalesRecord(barcode, LocalDate.now(), lastScannedProduct.getPrice());
            for (SalesRecord sr :
                    salesCache.values()) {
                if (sr.getBarcode() == barcode) {
                    existing = sr;
                }
            }
            for (Product pr :
                    salesCache.keySet()) {
                if (pr.getBarcode() == barcode) {
                    lastScannedProduct = pr;
                }
            }
            existing.increaseQuantity(1);
            quantity++;
            salesCache.put(lastScannedProduct, existing);
        } else {
            for (Product pr :
                    salesCache.keySet()) {
                if (pr.getBarcode() == barcode) {
                    lastScannedProduct = pr;
                }
            }
            SalesRecord salesRecord = new SalesRecord(barcode, LocalDate.now(), lastScannedProduct.getPrice());
            salesCache.put(lastScannedProduct, salesRecord);
        }
        if (lastScannedProduct.isPerishable() == false) {
            //salesService.lookupProduct(barcode);
            ui.displayProduct(lastScannedProduct);

        } else if ((lastScannedProduct.isPerishable() == true)) {
            ui.displayCalendar();
            //correctSalesPrice();
        } else {
            ui.displayErrorMessage("Unknown Product!");
            //throw new UnknownProductException("");
        }


    }

    /**
     * Submit the sales to the sales service, finalizing the sales transaction.
     * All salesRecords in the salesCache are stored (one-by-one) in the salesService.
     * All caches are reset.
     */
    public void finalizeSalesTransaction() {
        //TODO implement finalizeSalesTransaction()
        for (SalesRecord sr :
                salesCache.values()) {
            salesService.sold(sr);
        }
        salesCache.clear();


//        SalesRecord salesRecord = new SalesRecord(lastScannedProduct.getBarcode(), clock , lastScannedProduct.getPrice())
//
//        salesService.sold(salesRecord);

}

    /**
     * Correct the sales price of the last scanned product by considering the
     * given best before date, then submit the product to the service and save
     * in list.
     *
     * This method consults the clock to see if the product is eligible for a
     * price reduction because it is near or at its best before date.
     * 
     * Precondition is that the last scanned product is the perishable product. 
     * You don't need to check that in your code. 
     * 
     * To find the number of days from now till the bestBeforeDate, use
     * LocalDate.now(clock).until(bestBeforeDate).getDays();
     * 
     * Depending on the number of days, update the price in the salesRecord folowing the 
     * pricing strategy as described in the assignment
     *
     * Update the salesRecord belonging to the last scanned product if necessary, so 
     * update the price and set the BestBeforeDate.
     * 
     * @param bestBeforeDate
     * @throws UnknownBestBeforeException in case the best before date is null.
     */
    public void correctSalesPrice(LocalDate bestBeforeDate) throws UnknownBestBeforeException {
        //TODO implement correctSalesPrice
        int percentOff = 0;
        int remainingPricePerc = 100;
//        for (Product pr :
//                salesCache.keySet()) {
//            if (pr.getBarcode() == barcode) {
//                lastScannedProduct = pr;
//            }
//        }
        int brc = lastScannedProduct.getBarcode();
        SalesRecord sc = null;
        for (SalesRecord sr :
                salesCache.values()) {
                if (sr.getBarcode() == brc) {
                    sc = sr;
                }
        }
       if (bestBeforeDate == null) {
           ui.displayErrorMessage("Best before Date is null");
       } else {
           //Number of days left till expiring
           int left =  LocalDate.now(clock).until(bestBeforeDate).getDays();
           if (left >= 2) {
               percentOff = 0;
               remainingPricePerc = 100;

           } else if (left == 1) {
               percentOff = 30;
               remainingPricePerc = 65;

           } else if ( left == 0) {
               percentOff = 65;
               remainingPricePerc = 35;

           } else if (left < 0) {
               percentOff = 100;
               remainingPricePerc = 0;

           }
           int beforePrice = lastScannedProduct.getPrice();
           int afterPrice = beforePrice/100 * remainingPricePerc;
           sc.setSalesPrice(afterPrice);
           sc.setBestBeforeDate(bestBeforeDate);

       }

        
    }

    /**
     * Print the receipt for all the sold products, to hand the receipt to the
     * customer. The receipt contains lines containing: the product description,
     * the (possibly reduced) sales price per piece and the quantity, separated by
     * a tab.
     * The order of printing is the order of scanning, however Perishable
     * products are printed first. The non-perishables afterwards.
     */
    public void printReceipt() {
        //TODO implement printReceipt
//        Collection prko =new ArrayList();
//        for (Product pr :
//                salesCache.keySet()) {
//            lastScannedProduct = pr;
//            prko.add(lastScannedProduct.getDescription());
//            prko.add(lastScannedProduct.getPrice());
//
//        }
//        for (SalesRecord sr :
//                salesCache.values()) {
//            prko.add(sr.getSalesPrice());
//            prko.add(sr.getQuantity());
//        }
//
//        for (Entry:
//             prko.stream().toArray()) {
//
//        }
        for (Product pr :
                salesCache.keySet()) {
            printer.println(pr.getDescription() + "\t"  + pr.getPrice() + "\t" + quantity);

        }

        
    }
}

CashRegisterTest.Class :

@ExtendWith(MockitoExtension.class)
public class CashRegisterTest {

    Product lamp = new Product("led lamp", "Led Lamp", 250, 1_234, false);
    Product banana = new Product("banana", "Bananas Fyffes", 150, 9_234, true);
    Product cheese = new Product("cheese", "Gouda 48+", 800, 7_687, true);
    Clock clock = Clock.systemDefaultZone();

    Map<String, Product> products = Map.of(
            "lamp", lamp,
            "banana", banana,
            "cheese", cheese
    );

    @Mock
    Printer printer;

    @Mock
    SalesService salesService;

    @Mock
    UI ui;

    @Captor
    private ArgumentCaptor<SalesRecord> salesRecordCaptor;

    @Captor
    private ArgumentCaptor<Product> productCaptor;

    @Captor
    private ArgumentCaptor<String> stringLineCaptor;

    CashRegister cashRegister;

    @BeforeEach
    void setup() {
        cashRegister = new CashRegister(clock, printer, ui, salesService);
    }

    /**
     * Test that after a scan, a non perishable product is looked up and
     * correctly displayed.Have a look at requirements in the JavaDoc of the
     * CashRegister methods. Test product is non-perishable, e.g. led lamp.
     * <ul>
     * <li>Train the mocked salesService and check if a lookup has been
     * done.<li>Check if the mocked UI was asked to display the
     * product.<li>Ensure that ui.displayCalendar is not called.<b>NOTE
     *
     * @throws ps.UnknownProductException
     */
    @Test
    public void lookupandDisplayNonPerishableProduct() throws UnknownProductException {

        //TODO 1 Implement Test Method and write necessary implementation in scan() method of CashRegister
        //when()
            cashRegister.scan(lamp.getBarcode());
            ui.displayProduct(lamp);
            assertThat(lamp.isPerishable()).isFalse();
            verify(ui, times(0)).displayCalendar();

        //fail( "method lookupandDisplayNonPerishableProduct reached end. You know what to do." );
    }

    /**
     * Test that both the product and calendar are displayed when a perishable
     * product is scanned.
     *
     * @throws UnknownProductException but don't worry about it, since you test
     * with an existing product now.
     */
    @Test
    public void lookupandDisplayPerishableProduct() throws UnknownProductException {
        //TODO 2 Implement Test Method and write necessary implementation in scan() method of CashRegister
        cashRegister.scan(banana.getBarcode());
        ui.displayProduct(banana);
        assertThat(banana.isPerishable()).isTrue();
        verify(ui).displayCalendar();
        //fail( "method lookupandDisplayPerishableProduct reached end. You know what to do." );
    }

    /**
     * Scan a product, finalize the sales transaction, then verify that the
     * correct salesRecord is sent to the SalesService. Use a non-perishable
     * product. SalesRecord has no equals method (and do not add it), instead
     * use {@code assertThat(...).usingRecursiveComparison().isEqualTo(...)}.
     * Also verify that if you print a receipt after finalizing, there is no output.
     *
     * @throws ps.UnknownProductException
     */
    @Test
    public void finalizeSalesTransaction() throws UnknownProductException {
        //TODO 3 Implement Test Method and write necessary implementation in finalizeSalesTransaction() method of CashRegister
        cashRegister.scan(lamp.getBarcode());
        cashRegister.finalizeSalesTransaction();
        SalesRecord expected = new SalesRecord(lamp.getBarcode(), LocalDate.now(), lamp.getPrice());
        stringLineCaptor = ArgumentCaptor.forClass(String.class);
        salesRecordCaptor = ArgumentCaptor.forClass(SalesRecord.class);
        assertThat(salesRecordCaptor.capture()).usingRecursiveComparison().isEqualTo(expected);
        cashRegister.printReceipt();
        verify(printer, times(0)).println(stringLineCaptor.capture());

        //fail( "method finalizeSalesTransaction reached end. You know what to do." );
    }

    /**
     * Verify price reductions. For a perishable product with: 10 days till
     * best-before, no reduction; 2 days till best-before, no reduction; 1 day
     * till best-before, 35% price reduction; 0 days till best-before (so sales
     * date is best-before date), 65% price reduction; -1 days till best-before
     * (product over date), 100% price reduction.
     *
     * Check the correct price using the salesService and an argument captor.
     */
    @ParameterizedTest
    @CsvSource({
        "banana,10,100",
        "banana,2,100",
        "banana,1,65",
        "banana,0,35",
        "banana,-1,0",})
    public void priceReductionNearBestBefore(String productName, int daysBest, int pricePercent) throws UnknownBestBeforeException, UnknownProductException {
        //TODO 4 Implement Test Method and write necessary implementation in correctSalesPrice() method of CashRegister
        LocalDate days = LocalDate.now().plusDays(daysBest);
        productCaptor = ArgumentCaptor.forClass(Product.class);
        cashRegister.correctSalesPrice(days);


        salesRecordCaptor = ArgumentCaptor.forClass(SalesRecord.class);

        //salesService;

        verify(salesRecordCaptor.capture()).setSalesPrice(productCaptor.capture().getPrice()/100*pricePercent);


        //assertThat(cashRegister.correctSalesPrice(daysBest))
        //fail( "method priceReductionNearBestBefore reached end. You know what to do." );
    }

    /**
     * When multiple products are scanned, the resulting lines on the receipt
     * should be perishable first, not perishables last. Scan a banana, led lamp
     * and a cheese. The products should appear on the printed receipt in
     * banana, cheese, lamp order. The printed product line on the receipt
     * should contain description, (reduced) salesprice per piece and the
     * quantity.
     *
     */
    @Test
    public void printInProperOrder() throws UnknownBestBeforeException, UnknownProductException {
        //TODO 5 Implement Test Method and write necessary implementation in printReceipt() method of CashRegister
        cashRegister.scan(lamp.getBarcode());
        cashRegister.scan(banana.getBarcode());
        cashRegister.scan(cheese.getBarcode());

        StringBuilder str = new StringBuilder();
        str.append(lamp.toString());
        str.append(banana.toString());
        str.append(cheese.toString());

        stringLineCaptor = ArgumentCaptor.forClass(String.class);
        List<Product> expected = new ArrayList<>();
        salesRecordCaptor = ArgumentCaptor.forClass(SalesRecord.class);
        List<SalesRecord> actual = salesRecordCaptor.getAllValues();
        cashRegister.printReceipt();
        InOrder inOrder = Mockito.inOrder();


        verify(stringLineCaptor.capture()).equals(str.toString());
       // fail( "method printInProperOrder reached end. You know what to do." );
    }

    /**
     * Test that invoking correctSalesPrice with null parameter results in
     * exception.
     *
     * @throws UnknownProductException (but that one is irrelevant). First scan
     * (scan) a perishable product. Afterwards invoke correctSalesPrice with
     * null parameter. An UnknownProductException should be thrown.
     */
    @Test
    public void correctSalesPriceWithBestBeforeIsNullThrowsException() throws UnknownProductException {
        try {
            Product rhino = new Product("rhino", "Rhino", 250, 1_234, true);
            cashRegister.scan(rhino.getBarcode());
            LocalDate da = null;
            cashRegister.correctSalesPrice(da);
            fail("Should have thrown UnknownBestBeforeException");
        }
        catch (UnknownBestBeforeException e){
                System.out.println(e);
            }
        //TODO 6 Implement Test Method and write necessary implementation in correctSalesPrice() method of CashRegister
        //fail( "method correctSalesPriceWithBestBeforeIsNull reached end. You know what to do." );
    }

    /**
     * Test scanning an unknown product results in error message on GUI.
     */
    @Test
    public void lookupUnknownProductShouldDisplayErrorMessage() throws UnknownProductException {

        //TODO 7 Implement Test Method and write necessary implementation in scan() method of CashRegister
        Product rhino = new Product("rhino", "Rhino", 250, 1_234, false);
        stringLineCaptor = ArgumentCaptor.forClass(String.class);
        cashRegister.scan(rhino.getBarcode());
        //when(cashRegister.scan(rhino.getBarcode())).thenThrow(UnknownProductException.class);
        verify(ui).displayErrorMessage(stringLineCaptor.capture());
        //fail( "method lookupUnknownProduct... reached end. You know what to do." );
    }

    /**
     * Test that a product that is scanned twice, is registered in the
     * salesService with the proper quantity AND make sure printer prints the
     * proper quantity as well.
     *
     * @throws UnknownProductException
     */
    @Test
    public void scanProductTwiceShouldIncreaseQuantity() throws UnknownProductException {
        cashRegister.scan(lamp.getBarcode());
        cashRegister.scan(lamp.getBarcode());
        verify(salesService, times(2)).lookupProduct(lamp.getBarcode());
        //TODO 8 Implement Test Method and write necessary implementation in scan() method of CashRegister
        //fail( "method scanProductTwice reached end. You know what to do." );
    }
}

ErrorMessage:

java.lang.NullPointerException
    at ps.CashRegister.scan(CashRegister.java:92)
    at ps.CashRegisterTest.lookupandDisplayNonPerishableProduct(CashRegisterTest.java:81)
    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:567)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
    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:210)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:206)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:131)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65)
    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:129)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1507)
    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:143)
    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:129)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1507)
    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:143)
    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:129)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    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.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:75)
    at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
    at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
  • 1
    The heuristic for debugging a NullPointerException is almost always the same: You should critically read your exception's stacktrace to find the line of code at fault, the line that throws the exception, and then inspect that line carefully, find out which variable is null, and then trace back into your code to see why. You will run into these again and again, trust me. In the future, please search on the subject before posting, since this is too common a problem to post yet another NPE question. – Hovercraft Full Of Eels Mar 20 '22 at 16:46
  • You seem to already be aware of the problem that some pointer is supposed to be set to some value, but it isn't, so what exactly is your question? – mkrieger1 Mar 20 '22 at 16:46
  • So, 1) please post the stack trace. 2) show the line that throws the exception. 3) tell which variable on that line is null and why you think that it shouldn't be null... – Hovercraft Full Of Eels Mar 20 '22 at 16:46
  • @mkrieger1 problem is that I am trying to change the products value by having the foreach loop through the Map but it doesn't seem to work, first error is on line 92 where I try to get the price of the lastScannedProduct – Ondra Hrubý Mar 20 '22 at 16:52
  • @HovercraftFullOfEels ```java.lang.NullPointerException at ps.CashRegister.scan(CashRegister.java:92) at ps.CashRegisterTest.lookupandDisplayNonPerishableProduct(CashRegisterTest.java:81) at java.base/java.util.ArrayList.forEach(ArrayList.java:1507) at java.base/java.util.ArrayList.forEach(ArrayList.java:1507)``` – Ondra Hrubý Mar 20 '22 at 16:52
  • Ondra: important information such as this should be posted in the question as an [edit], not in comments. Also, as previously requested, please indicate which line throws the exception, which line is `CashRegister.java:92`, the 92nd line of your class. Again, post that information *in the question itself*. – Hovercraft Full Of Eels Mar 20 '22 at 16:57
  • @HovercraftFullOfEels Line 92 is this '''SalesRecord salesRecord = new SalesRecord(barcode, LocalDate.now(), lastScannedProduct.getPrice());''' in the public void scan(int barcode) method. I'm sorry I'll add it as an edit – Ondra Hrubý Mar 20 '22 at 17:01
  • You will have to look into your own running code to see why `lastScannedProduct` stays null. Use of a debugger will help you with this. – Hovercraft Full Of Eels Mar 20 '22 at 17:16

0 Answers0