handling exception for RestAPI unit test - unit-testing

I have a method
public class ActivityManager {
private ActivityManager activityManager_;
#Autowired
public ActivityManager(ActivityManager activityManage)
{
activityManager_= activityManage;
}
#RequestMapping(value ="activityManager/", method = RequestMethod.GET)
public List<Data> getData() throws RestControllerException {
try {
return activityManage_.fetchData();
} catch (Exception ex) {
throw new RestControllerException();
}
}
}
And I tried to test the throw exception but it does not work. I got confused into the case what's the status() for resultmatcher should be.
#Test(expected = RestControllerException.class)
public void getDataError() throws Exception {
ActivityManager activityManagerMock = Mockito.mock(ActivityManager
.class);
doThrow(RestControllerException.class).when(activityManagerMock).fetchData();
mockMvc_.perform(get("/activityManager")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isInternalServerError());
}
Is there any document that I can read more about handling exception for restapi unit test?
Thanks

#Autowired
private ActivityManagerService activityManager;
This will inject the actual bean into the controller not the mock which you created.
Add this inside your test class.
#Autowired
private ControllerBean controller;
#Before
public void init(){
ReflectionTestUtils.setField(controller, "activityManager", activityManagerMock);
}
This will set the MockObject into activityManager of Controller.
And hence while running test the mock objects fetchData() will be called which inturn throws the exception.

Related

Mockito Test Failure - Actually, there were zero interactions with this mock

Is there any other way to write test case for below case, needs to write test case for runStudentService method . Tried to write test case as below but its throwing : "wanted but not invoked - Actually, there were zero interactions with this mock."
#Component
public class StudentScheduler {
#Autowired
private StudentService studentService;
#Scheduled(cron = "${cron.students}")
public void runStudentService() {
try {
studentService.startStudetsTest();
} catch (Exception e) {
LOG.error("Error occured during test" + e);
throw(e);
}
}
}
#RunWith(SpringJUnit4ClassRunner.class)
public class StudentSchedulerTest {
#Mock
private StudentService studentService;
StudentScheduler scheduler = Mockito.mock(StudentScheduler.class);
#Test
public void jobRuns() {
Mockito.doNothing().when(scheduler).runStudentService();
verify(scheduler, Mockito.times(1)).runStudentService();
}
}
Your mocked StudentScheduler class is not using your mocked studentService instance. Double check the instance studentService instance inside the runStudentService() function is the same instance as your mock studentService.
Pass that mocked studentService instance into the runStudentService() function to be invoked!

Mockmvc Controller throws NullPointerException

maybe someone can tell me why I always get NullPointerException when testing my Controller.
It tells me that the NullPointerException happens here:
mvc.perform(get("/passwordaenderung"))
Here is my code:
public class LagerstandortControllerTest {
#InjectMocks
private PasswordChange passwordChange;
// add #Mock annotated members for all dependencies used by the controller here
private MockMvc mvc;
// add your tests here using mvc.perform()
#Test
public void getHealthStatus() throws Exception {
mvc.perform(get("/passwordaenderung"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.status", is("OK")));
}
#Before
public void createControllerWithMocks() {
MockitoAnnotations.initMocks(this);
MockMvcBuilders.standaloneSetup(new PasswordChange()).build();
}
}
What I want to achieve is to test my controller without loading the whole ApplicationContext.
I had to adapt it in order to avoid a NullPointerException:
Introduced a new class:
public class StandaloneMvcTestViewResolver extends InternalResourceViewResolver {
public StandaloneMvcTestViewResolver() {
super();
}
#Override
protected AbstractUrlBasedView buildView(final String viewName) throws Exception {
final InternalResourceView view = (InternalResourceView) super.buildView(viewName);
// prevent checking for circular view paths
view.setPreventDispatchLoop(false);
return view;
}
}
And in my setup method:
#Before
public void setUp() {
final MainController controller = new MainController();
mvc = MockMvcBuilders.standaloneSetup(controller)
.setViewResolvers(new StandaloneMvcTestViewResolver())
.build();
}
The only problem is now that I get a 404 error.
Do I have to put my index.html in
/src/test/resources
too?

Unit testing middleware with NUnit and NSubstitute

I've written a bit of middleware in an ASP.NET Core site and I'm trying to unit test it, mainly by following this guide that uses Moq.
My problem is finding an NUnit/NSubstitute equivalent for new DefaultHttpContext(). Substituting HttpContext will trigger the middleware, but it passes the try. I presume this is because of the issue quoted below. Does NUnit have a function to create a real HttpContext, or am I looking at a lot more infrastructure to achieve this?
I am sending an instance of DefaultHttpContext to the Invoke method. I can't use a mocked HttpContext in this scenario because the first middleware (the lambda function that we passed to the constructor) will need to write to the response. Hence the HttpResponse needs to be a real object not mocked.
Here is the code for my Test
[TestFixture]
public class ExceptionHelperTests
{
private IErrorRepository errorRepository;
private ExceptionHandler handler;
[SetUp]
public void Setup()
{
errorRepository = Substitute.For<IErrorRepository>();
}
[Test]
public async void Given_AnExceptionHappens_Then_ItShouldBeLogged()
{
// Arrange
const string username = "aUser";
var user = Substitute.For<ClaimsPrincipal>();
user.Identity.Name.Returns(username);
handler = new ExceptionHandler(
next: async (innerHttpContext) =>
{
innerHttpContext.User = user;
},
repository: errorRepository);
// Act
await handler.Invoke(new DefaultHttpContext());
// Assert
errorRepository.Received().LogException(Arg.Any<string>(), Arg.Any<Exception>(), Arg.Is(username));
}
}
Here is the IErrorRepository
public interface IErrorRepository
{
Exception LogException(string message, Exception ex, string userId);
void LogMessage(string message, string errorDetail, string userId);
}
And here is the middleware (with a simplified HandleException):
public sealed class ExceptionHandler
{
private readonly RequestDelegate _next;
private readonly IErrorRepository repository;
public ExceptionHandler(RequestDelegate next, IErrorRepository repository)
{
_next = next;
this.repository = repository;
}
public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
catch (Exception ex)
{
HandleException(ex, context.User.Identity.Name);
}
}
public void HandleException(Exception ex, string userId)
{
repository.LogException("An unhandled exception has occurred.", ex, userId);
}
}
DefaultHttpContext is just the default implementation of HttpContext abstract class.
You just could do
var HttpContextSub = Substitute.For<HttpContext>();

getExchange from mockEndPoint in a unit-test class for Camel Route Not Behaving As Expected

I want to getExchanges from a mockEndPoint in a unit-test class for Camel Route but it doesn't work.
Here is my unit test class:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration("classpath:camel-unit-test.xml")
public class ImportDatabaseRouteTest extends CamelTestSupport {
#Value("${sql.importDatabase}")
String oldEndPoint;
#Autowired
private ImportDatabaseRoute importDatabaseRoute;
#Autowired
private DriverManagerDataSource dataSource;
#Override
protected RouteBuilder createRouteBuilder() throws Exception {
return importDatabaseRoute;
}
#Before
public void mockEndpoints() throws Exception {
AdviceWithRouteBuilder adviceTest = new AdviceWithRouteBuilder() {
#Override
public void configure() throws Exception {
interceptSendToEndpoint(oldEndPoint)
.skipSendToOriginalEndpoint()
.to("mock:catchCSVList");
}
};
context.getRouteDefinitions().get(0).adviceWith(context, adviceTest);
}
#Override
public boolean isUseAdviceWith() {
return true;
}
#Override
protected JndiRegistry createRegistry() throws Exception {
JndiRegistry jndi = super.createRegistry();
//use jndi.bind to bind your beans
jndi.bind("dataSource", dataSource);
return jndi;
}
#Test
public void testTheImportRoute() throws Exception {
MockEndpoint mockEndPointTest = getMockEndpoint("mock:catchCSVList");
context.start();
List<List<String>> test = (List<List<String>>) mockEndPointTest.getExchanges().get(0).getIn().getBody();
assertEquals("4227",test.get(1).get(0));
assertEquals("370",test.get(1).get(1));
assertEquals("",test.get(1).get(2));
mockEndPointTest.expectedMessageCount(1);
mockEndPointTest.assertIsSatisfied();
context.stop();
}
}
And here are the results:
java.lang.ArrayIndexOutOfBoundsException: 0
at java.util.concurrent.CopyOnWriteArrayList.get(CopyOnWriteArrayList.java:387)
Please help me to fix it. Thank you so much.
You have to assert the mock before you get the exchanges. As those exchanges are the actual exchange that arrived at the mock. So its expectations has to be meet first, which says 1 message should arrive. And if that is success, then you can get that exchange via index 0, and you will not get an IndexOutOfBoundsException
MockEndpoint mockEndPointTest = getMockEndpoint("mock:catchCSVList");
context.start();
// set expectations on mock here
mockEndPointTest.expectedMessageCount(1);
mockEndPointTest.assertIsSatisfied();
// okay now we can get the exchange's from the mock
List<List<String>> test = (List<List<String>>) mockEndPointTest.getExchanges().get(0).getIn().getBody();
assertEquals("4227",test.get(1).get(0));
assertEquals("370",test.get(1).get(1));
assertEquals("",test.get(1).get(2));
context.stop();

JUnit Tests for Liferay MVCPortlet using PowerMock

Im trying to make JUnit Test using PowerMock, but I have one problem. Here is my code:
public class MyGreeting extends MVCPortlet {
public static final String GREETING="greeting";
private static final String DEFAULT_GREETING="MY DEFAULT GREETING MESSAGE";
private static final Log _log = LogFactoryUtil.getLog(MyGreeting.class.getName());
#Override
public void render(RenderRequest req,RenderResponse res)
throws IOException, PortletException {
PortletPreferences prefs = req.getPreferences();
req.setAttribute(GREETING, prefs.getValue(GREETING, DEFAULT_GREETING));
super.render(req,res);
}
And I need to make JUnit test. I created another test package, new MyGreetingTest.java file, and come up to this code:
public class MyGreetingTest extends Mockito{
#BeforeClass
public static void setUpBeforeClass() throws Exception {
}
#AfterClass
public static void tearDownAfterClass() throws Exception {
}
private MyGreeting portlet;
#Before
public void setUp() throws Exception {
portlet = new MyGreeting();
}
#After
public void tearDown() throws Exception {
}
#Mock
public RenderRequest request = mock(RenderRequest.class);
#Mock
PortletPreferences preferences = mock(PortletPreferences.class);
#Test
public final void renderTest() throws IOException, PortletException {
when(request.getPreferences()).thenReturn(preferences);
when(preferences.getValue(MyGreeting.GREETING, null)).thenReturn(value);
portlet.render(request, null);
String result = request.getAttribute(MyGreeting.GREETING).toString();
assertEquals(result, value);
}
But I have NullPointerException, because we can't apply getAttribute method to mock-request. Could you please tell me how to solve this problem? How can I test method with getAttribute method using Mockito?
I think you need to mock your method
Stock stock = mock(Stock.class);
when(stock.getPrice()).thenReturn(100.00); // Mock implementation
when(stock.getValue()).thenCallRealMethod(); // Real implementation