Writing Junit by using Mockito for batch Update - junit5

Can please write the JUnit code by using Mockito for the following code :
public void writeToNoClaimLeftBehindMMF(List<NoClaimLeftMedicaidMaster> nclmm) throws Exception {
String query = Queries.NO_CLAIM_LEFT_MMF_INSERT_QUERY;
MapSqlParameterSource[] params = new MapSqlParameterSource[nclmm. Size()];
for (int i = 0; i < nclmm. Size(); i++) {
params[i] = new MapSqlParameterSource()
.addValue("envId", nclmm.get(i).getENV_ID());
mysqlJdbcTemplate.batchUpdate(query, params);

It depends on what exact behaviour of writeToNoClaimLeftBehindMMF you are trying to test. Assuming that you want to mock your mysqlJdbcTemplate instance, you will have to inject the mock as a class constructor argument and the test code would be something like this:
#Test
public void whenEmptyListIsPassed_thenWriteToNoClaimLeftBehindMMFGoesBlahBlah() {
// Given
var mockJdbcTemplate = mock(JdbcTemplate.class);
when(mockJdbcTemplate.batchUpdate(...,...)).thenReturn(whatever);
var systemUnderTest = new WhateverYourClassIsCalled(mockJdbcTemplate);
// When
systemUnderTest.writeToNoClaimLeftBehindMMF(List.of());
// Then
assertTrue(whatever you're testing);
}
See https://javadoc.io/doc/org.mockito/mockito-core/latest/index.html

Related

Xunit Unit Testing for Dot Net core application

I recently started learning Unit Testing and now have the requirement write unit tests using Xunit and Moq for dot net core application.
I can write some very basic but when it comes to write them for complex classes , I am kind of stuck.
Below is the class I will be writing tests for.
public class AgeCategoryRequestHandler : IInventoryRequestHandler<InventoryRequest, HandlerResult>
{
private readonly IRepositoryResolver _repositoryResolver;
Hotels.HBSI.Logging.ILogger logger;
public AgeCategoryRequestHandler(IRepositoryResolver repositoryResolver, Hotels.HBSI.Logging.ILogger iLogger)
{
_repositoryResolver = repositoryResolver;
logger = iLogger;
}
public async Task<HandlerResult> Run(InventoryRequest inventoryRequest)
{
var result = await ProcessRequest(inventoryRequest);
return CreateResponse(inventoryRequest, result);
}
private async Task<int> ProcessRequest(InventoryRequest inventoryRequest)
{
logger.Info("AgeCategory requesthandler processrequest start");
var repository = _repositoryResolver.ResolveEstabAgeCategory();
if (repository is not null)
{
return await repository.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories)
.ConfigureAwait(false);
}
logger.Info("AgeCategory requesthandler processrequest complete");
return InernalError.reponotfound;
}
public HandlerResult CreateResponse(InventoryRequest inventoryRequest, int resultCount)
{
var requestCount = inventoryRequest.EstabAgeCategories.Count;
var handlerResult = new HandlerResult() { Id = RequestHandlerEnum.AgeCategrory.ToInt() };
if (requestCount > 0 && resultCount < requestCount)
{
handlerResult.IsSuccess = false;
handlerResult.ErrorCode = OTAErrorType.InvalidAgeCategory.ToInt();
}
else if (requestCount > 0 || requestCount == resultCount)
{
handlerResult.IsSuccess = true;
handlerResult.ErrorCode = 0;
}
return handlerResult;
}
}
Just to start , IRepositoryResolver and ILogger are in the constructor so I have created mock for these but unable to go beyond that as I am still in initial phase of learning.
Could someone explain me the steps/approach to accomplish this?.
Edit : What I have done so far is below ( can't figure out what are the things to be done and where to start or write )
Edit 2 : Did some more modifications to my test code , can someone comment if I am in right direction ? what else can I test ?
public class AgeCategoryRequestHandlerTest
{
private AgeCategoryRequestHandler _ageCategoryRequestHandler;
private readonly Mock<AgeCategoryRequestHandler> _ageCategory = new Mock<AgeCategoryRequestHandler>();
private readonly Mock<Hotels.HBSI.Logging.ILogger> _mockLogger = new Mock<Hotels.HBSI.Logging.ILogger>();
private readonly Mock<IRepositoryResolver> _mockRepositoryResolver = new Mock<IRepositoryResolver>();
public AgeCategoryRequestHandlerTest()
{
_ageCategoryRequestHandler = new AgeCategoryRequestHandler(_mockRepositoryResolver.Object, _mockLogger.Object);
}
[Fact]
public async void Testtt()
{
var fixture = new Fixture();
var inventory = fixture.Create<InventoryRequest>();
var hndlr = fixture.Create<HandlerResult>();
hndlr.ErrorCode = 0;
int resultCount = 3;
await _ageCategoryRequestHandler.Run(inventory);
HandlerResult response = _ageCategoryRequestHandler.CreateResponse(inventory, resultCount);
Assert.Equal(hndlr.ErrorCode, response.ErrorCode);
}
Tried running Chris B suggested code , was getting type conversion error EstabAgeCategories = new List<int>
Now I have used fixture for creating automatic objects and did some assert values. Below is the code sample
var fixture = new Fixture();
var inventoryRequest = fixture.Create<InventoryRequest>();
_mockRepository
.Setup(x => x.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories))
.ReturnsAsync(6);
_mockRepositoryResolver
.Setup(x => x.ResolveEstabAgeCategory())
.Returns(_mockRepository.Object);
// act
var result = await _ageCategoryRequestHandler.Run(inventoryRequest);
// assert
_mockRepository
.Verify(x => x.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories), Times.Once);
Assert.True(result.Id == 6);
Assert.True(result.ErrorCode == 0);
Assert.True(result.IsSuccess);
From the unit test code you've posted, it looks like you are getting confused on what to test.
Look at your class and identify your "public" interface i.e. what methods can be called from other parts of your code. You should really only test public methods. Private methods are usually tested via public methods.
Looking at AgeCategoryRequestHandler, you have two public methods - Run and CreateResponse. I would question whether CreateResponse needs to be public but we'll leave it for now. For each of these methods, you want to be asserting that the returned value is what you expect given the input value.
private AgeCategoryRequestHandler _ageCategoryRequestHandler;
// Not needed
private readonly Mock<AgeCategoryRequestHandler> _ageCategory = new Mock<AgeCategoryRequestHandler>();
private readonly Mock<Hotels.HBSI.Logging.ILogger> _mockLogger = new Mock<Hotels.HBSI.Logging.ILogger>();
private readonly Mock<IRepositoryResolver> _mockRepositoryResolver = new Mock<IRepositoryResolver>();
public AgeCategoryRequestHandlerTest()
{
_ageCategoryRequestHandler = new AgeCategoryRequestHandler(_mockRepositoryResolver.Object, _mockLogger.Object);
}
The set up of the unit test is going the right way - you have created mocks for your dependencies but I see you have created a mock for the class you are trying to test - this is not needed and can be removed. You want to be testing the actual class itself which you are initializing in the constructor.
public async Task<HandlerResult> Run(InventoryRequest inventoryRequest)
{
var result = await ProcessRequest(inventoryRequest);
return CreateResponse(inventoryRequest, result);
}
private async Task<int> ProcessRequest(InventoryRequest inventoryRequest)
{
_logger.LogInformation("AgeCategory requesthandler processrequest start");
var repository = _repositoryResolver.ResolveEstabAgeCategory();
if (repository != null)
{
return await repository.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories).ConfigureAwait(false);
}
_logger.LogInformation("AgeCategory requesthandler processrequest complete");
return 0;
}
We can test the public Run method by looking at the method and seeing what it is going to do when executed. Firstly, it's going to call a private method ProcessRequest. Inside ProcessRequest, the IRepositoryResolver dependency is going to be used. This means we need to "set up" this dependency in our unit test to satisfy the if (repository != null) condition.
I assume the IRepositoryResolver returns another interface (?) - something like:
public interface IRepository
{
Task<int> InsertUpdateEstabAgeCategoryDetail(List<int> x);
}
So in your unit test, you need to create a mock for the repository being returned from IRepositoryResolver:
private readonly Mock<IRepository> _mockRepository = new Mock<IRepository>();
Then, you need to set up the mock IRepositoryResolver to return the mock repository above:
_mockRepositoryResolver
.Setup(x => x.ResolveEstabAgeCategory())
.Returns(_mockRepository.Object);
This is to satisfy the if (repository != null) condition.
_mockRepository
.Setup(x => x.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories))
.ReturnsAsync(6);
Next, you need to set up the InsertUpdateEstabAgeCategoryDetail() method on the mock repository to return a value. This value is being returned by ProcessRequest() and then used to call CreateResponse(inventoryRequest, result) as the result parameter.
if (requestCount > 0 && resultCount < requestCount)
{
handlerResult.IsSuccess = false;
handlerResult.ErrorCode = (int)OTAErrorType.InvalidAgeCategory;
}
else if (requestCount > 0 || requestCount == resultCount)
{
handlerResult.IsSuccess = true;
handlerResult.ErrorCode = 0;
}
Now you can look at the CreateResponse method and by setting different values for inventoryRequest.EstabAgeCategories and setting up the mock _mockRepository.Setup(x => x.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories)).ReturnsAsync(6); to return different values, you can satisfy the different paths through the if statement.
CreateResponse is returning an instance of HandlerResult which in turn is being returned by Task<HandlerResult> Run. This is the returned object you want to make assertions on.
One of the unit test cases might look like this (I have not tested it myself):
[Fact]
public async Task GivenInventoryRequest_WhenRun_ThenHandlerResultReturned()
{
// arrange
var inventoryRequest = new InventoryRequest
{
EstabAgeCategories = new List<int>
{
1, 2, 3, 4, 5
}
};
_mockRepository
.Setup(x => x.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories))
.ReturnsAsync(6);
_mockRepositoryResolver
.Setup(x => x.ResolveEstabAgeCategory())
.Returns(_mockRepository.Object);
// act
var result = await _ageCategoryRequestHandler.Run(inventoryRequest);
// assert
_mockRepository
.Verify(x => x.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories), Times.Once);
Assert.True(result.Id == 0);
Assert.True(result.ErrorCode == 0);
Assert.False(result.IsSuccess);
}

JUnit 5 Parameterized test #ArgumentsSource parameters not loading

I have created below JUnit5 parameterized test with ArgumentsSource for loading arguments for the test:
public class DemoModelValidationTest {
public ParamsProvider paramsProvider;
public DemoModelValidationTest () {
try {
paramsProvider = new ParamsProvider();
}
catch (Exception iaex) {
}
}
#ParameterizedTest
#ArgumentsSource(ParamsProvider.class)
void testAllConfigurations(int configIndex, String a) throws Exception {
paramsProvider.executeSimulation(configIndex);
}
}
and the ParamsProvider class looks like below:
public class ParamsProvider implements ArgumentsProvider {
public static final String modelPath = System.getProperty("user.dir") + File.separator + "demoModels";
YAMLDeserializer deserializedYAML;
MetaModelToValidationModel converter;
ValidationRunner runner;
List<Configuration> configurationList;
List<Arguments> listOfArguments;
public ParamsProvider() throws Exception {
configurationList = new ArrayList<>();
listOfArguments = new LinkedList<>();
deserializedYAML = new YAMLDeserializer(modelPath);
deserializedYAML.load();
converter = new MetaModelToValidationModel(deserializedYAML);
runner = converter.convert();
configurationList = runner.getConfigurations();
for (int i = 0; i < configurationList.size(); i++) {
listOfArguments.add(Arguments.of(i, configurationList.get(i).getName()));
}
}
public void executeSimulation(int configListIndex) throws Exception {
final Configuration config = runner.getConfigurations().get(configListIndex);
runner.run(config);
runner.getReporter().consolePrintReport();
}
#Override
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
return listOfArguments.stream().map(Arguments::of);
// return Stream.of(Arguments.of(0, "Actuator Power"), Arguments.of(1, "Error Logging"));
}}
In the provideArguments() method, the commented out code is working fine, but the first line of code
listOfArguments.stream().map(Arguments::of)
is returning the following error:
org.junit.platform.commons.PreconditionViolationException: Configuration error: You must configure at least one set of arguments for this #ParameterizedTest
I am not sure whether I am having a casting problem for the stream in provideArguments() method, but I guess it somehow cannot map the elements of listOfArguments to the stream, which can finally take the form like below:
Stream.of(Arguments.of(0, "Actuator Power"), Arguments.of(1, "Error Logging"))
Am I missing a proper stream mapping of listOfArguments?
provideArguments(…) is called before your test is invoked.
Your ParamsProvider class is instantiated by JUnit. Whatever you’re doing in desiralizeAndCreateValidationRunnerInstance should be done in the ParamsProvider constructor.
Also you’re already wrapping the values fro deserialised configurations to Arguments and you’re double wrapping them in providesArguments.
Do this:
#Override
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
return listOfArguments.stream();
}}

test objects created inside a method jmockit

The method which I wanted to test looks like:
public void method1(String str) {
ParmaObjectRequest request = new ParmaObjectRequest(str);
this.instanceVar.save(request);
}
I wanted to test if this.instanceVar.save is called with an ParmaObjectRequest object with str value using jmockit.
The test case I have written looks like below and I am able to test that my method is called 1 times but not the parameter inside it.
#Test
public void testMethod1() {
new Expectations() {
{
this.instanceVar.save((ParmaObjectRequest) any);
times = 1;
}
};
testObject.method1("dummyString");
}
But I also wanted to test that this.instanceVar.save is called with object containing "dummyString".
In the Expectations block, change "this.instanceVar" to "testObject.instanceVar"

How to pass bean class to a test method in testng?

I have an Excel Util which reads all the data from excel sheet. The excel sheet has 10 columns like time, sourceType, tid, message, severity,
lastModify, entityName, operationType, replayId, recordIds.
My DataProvider has code something like this which returns all the 10 columns and their values.
#DataProvider(name="googleData")
public static Object[][] testData() {
String filePath = "/Users/TestUser/Workspace/FixProject/ExcelCheck/src/test/resources/excelreader.xlsx";
Object[][] arrayObject = excelFileUtils.getExcelData(filePath, "excelreader");
return arrayObject;
}
In My TestMethod, I have to pass all these 10 columns or else it wont allow me to run. Instead I want to create a Bean Class and pass something like this to my test method
#Test(dataProvider = "googleData", dataProviderClass = DataProviders.class)
public void testGoogleData(BeanClass object) {
System.out.println(object.getTid());
}
How do we achieve this?
Using the dataProvider you have, your test method is going to run 10 times for each object in the array.
What you can do is to create an object, convert your dataProvider into that object and than use it your test method code.
Object myDataHelper = null;
#Test()
public void testGoogleData(BeanClass object) {
myDataHelper = convertDataProviderToObject();
// use it here in a for/for each loop
System.out.println(object.getTid());
}
public static Object[][] read_excel(String Sheet_Name) throws Exception
{
File obj = new File("./src/main/java/com/Demo/TestData/Test_Data.xlsx");
FileInputStream fis = new FileInputStream(obj);
XSSFWorkbook wb = new XSSFWorkbook(fis);
XSSFSheet sheet = wb.getSheet(Sheet_Name);
int row_number = sheet.getLastRowNum();
int column_number = sheet.getRow(0).getLastCellNum();
Object data[][] = new Object[row_number][column_number];
wb.close();
for(int i=0; i<row_number; i++)
{
for(int j=0; j<column_number; j++)
{
data[i][j] = sheet.getRow(i + 1).getCell(j).toString();
}
}
return data;
}
#DataProvider
public Object[][] getDataFromExcel() throws Exception
{ Object[][] data = Utility.read_excel("Admin_Credentials");//Sheet name
return data;
}
#Test(dataProvider="getDataFromExcel")
It is supported in QAF-TestNG extension. You can have one or more complex object argument in your test method while using inbuilt or custom data provider. For excel your code may look like below:
#QAFDataProvider(dataFile = "resources/data/googletestdata.xls")
#Test
public void testGoogleData(BeanClass object) {
System.out.println(object.getTid());
}
For custom data provider it may look like below:
#QAFDataProvider
#Test(dataProvider = "googleData", dataProviderClass = DataProviders.class)
public void testGoogleData(BeanClass object) {
System.out.println(object.getTid());
}
You need to make sure that,properties name in your bean class must match column names (in any order). When using custom data provider you need to return Iterator for List of Map<String, Object> or Object[][] having Map, refer few example if you required to create custom data provider.

How to rewrite removed "forEachInvocation" jmockit?

I have to upgrade from jmockit v0.999.15 to jmockit v1.33 and I am having issues rewriting a test which is using "forEachInvocation"
request.addParam(anyString, anyString); minTimes = 1; maxTimes = 10;
forEachInvocation = new Object() {
void validate(String someName, String someValue) {
if(Utils.XML.equals(someName)) {
assertTrue("incorrect value",someValue.contains("This is a test"));
}
}
};
The above piece of code is part of Expectations.
In jmockit website the following is mentioned, but I am not sure how to rewrite it:
"Version 1.7: Removed the forEachInvocation field, which was deprecated in release 1.6. Existing tests using it should instead take advantage of the withCapture() and withCapture(List) methods, or convert the handler object to a Delegate object assigned to the result field (in the case of a recorded expectation)."
It would be something like this:
List<String> someNames = new ArrayList<>();
List<String> someValues = new ArrayList<>();
request.addParam(withCapture(someNames), withCapture(someValues));minTimes = 1;maxTimes = 10;
for (String someName : someNames) {
// assert some name as/if needed
}
for (String someValue; someValues) {
// assert some values as/if needed
}