0

Its my early days with Mockito so need help. Because of the new() operator, a new object is getting created and the Mock is losing significance. Goal is to prevent execution of the stockValidator.validateRequest() method. Kindly note source code can't be modified. Sample code shared below,

Is there a way to mock the new() object?

StockResponse buyStock(StockRequest stockRequest) method{
.......
StockValidator stockValidator = new StockValidator(.....);
StockError error = stockValidator.validateRequest(StockRequest stockRequest);
}

StockError validateRequest(StockRequest stockRequest){
......
......
}

@MockBean
StockValidator stockValidator;
@Autowire
StockService stockService;

............
............

when(cardValidator.validateRequest(any(), any())).thenReturn(null);
StockResponse response = stockService.buyStock(stockRequest);
Shivayan Mukherjee
  • 766
  • 3
  • 10
  • 33
  • 1
    Please update the description to match the code and describe how the code doesn't work. – Torben Oct 13 '22 at 06:04
  • You cannot have `@MockBean StockValidator stockValidator` and `stockValidator = spy(new StockValidator())`. The assignment will overwrite the reference to the stock bean. The new reference is never used. Also read https://stackoverflow.com/questions/74027324/why-is-my-class-not-using-my-mock-in-unit-test/74027325, which showcases a similar problem – knittl Oct 13 '22 at 10:57
  • Does this answer your question? [Why is my class not using my mock in unit test?](https://stackoverflow.com/questions/74027324/why-is-my-class-not-using-my-mock-in-unit-test) – knittl Oct 13 '22 at 13:54

1 Answers1

0

Yes, there is a way to do what you will. Firstly, you do not need to use a spy. A spy is not a mock object. It is an instance on which you can call methods as you would normally, but with additional features.

so do not initialise stockValidator like that, but as:

stockValidator =  mock(StockValidator.class);

Or since you are already using @MockBean, you do not have to initialise manually at all. Mock object will NOT call the actual method, instead just make it return the value you tell it to return. Now you can allow the validateRequest() method return anything. Possibly

when(stockValidator.validateRequest(any(), any())).thenReturn(true);

Do not forget to initialise the service instance with the same validator object.

edit after change in question:

public class TestClass() {

  StockValidator stockValidator = mock(StockValidator.class);
  StockService stockService = new StockService(stockValidator);


  public void test() {

    when(stockValidator.validateRequest(any(), 
        any())).thenReturn(true);
    stockService.buyStock();
  }
}
Marius
  • 55
  • 1
  • 8
  • updated question and source code, kindly revisit to help. – Shivayan Mukherjee Oct 13 '22 at 12:50
  • @ShivayanMukherjee You cannot actually mock StockValidator when it is created in the method you are calling from the test class. What You could do though, is init Stockvalidator in stockService constructor as a bean and then mock stockValidator object in the test class.Like this: `public class TestClass() { StockValidator stockValidator = mock(StockValidator.class); StockService stockService = new StockService(stockValidator); test() { when(stockValidator.validateRequest(any(), any())).thenReturn(true); stockService.buyStock() } }` – Marius Oct 13 '22 at 13:24
  • You are not using the mock, please see [Why is my class not using my mock in unit test?](https://stackoverflow.com/questions/74027324/why-is-my-class-not-using-my-mock-in-unit-test) – knittl Oct 13 '22 at 14:30