How can I write UnitTest for service method with REQUIRES_NEW and constraint in DB - unit-testing

How can I create UnitTest for this method?
#Transactional(propagation = Propagation.REQUIRES_NEW)
#Override
public Charge saveInNewTransaction(Charge charge) {
if (charge.getIsDuplicate()) {
charge.setIsActive(false);
} else {
Charge chargeOrigin = charge.getChargeOrigin();
chargeOrigin.setIsActive(false);
chargesRepository.saveAndFlush(chargeOrigin);
}
return chargesRepository.saveAndFlush(charge);
}
I have constraint - only one can be isActive = true
I have no idea how to write a test for this method.
brief background. I get a list of charges for example 10 and in a cycle I try to save them. if i get an constraint exception - I need ignore it(and continue save another charges. I do not need rolback main transaction).
therefore I have such a method which is executed in REQUIRES_NEW transaction.
EDIT
I trying:
#MockBean
private ChargeRepository chargeRepository;
#Before
public void setUp() throws Exception {
chargeService = new ChargeServiceImpl(chargeRepository);
}
#Test
public void saveInNewTransaction() {
Charge charge = new Charge();
charge.setIsDuplicate(true);
Charge originCharge = new Charge();
originCharge.setIsDuplicate(false);
charge.setChargeOrigin(originCharge);
//when(???).thenReturn(???);
Charge savedCharge = chargeService.saveInNewTransaction(testCharge);
//assertThat(???);
}

Related

How to test an Update class in apex

Hello I am new to apex and soql, I would like some help on my test class, below is the code i am having trouble with,
public class UpdateMyCard {
#AuraEnabled(cacheable=false)
public static Card__c updateCard(Double Amount){
String userId = UserInfo.getUserId();
Card__c myCard = [SELECT Id, Card_no__c, total_spend__c From Card__c Where OwnerId =:userId];
myCard.total_spend__c = myCard.total_spend__c + Amount;
try{
update myCard;
}catch (Exception e) {
System.debug('unable to update the record due to'+e.getMessage());
}
return myCard;
}
}
Test Class
#isTest
public static void updatecard(){
UpdateMyCard.updateCard(200);
}
Error:
System.QueryException: List has no rows for assignment to SObject
Your code assumes there's already a Card record for this user. And it's exactly 1 record (if you have 2 your query will fail). I'm not sure what's your business requirement. Is it guaranteed there will always be such record? Should the code try to create one on the fly if none found? You might have to make that "updateCard" bit more error-resistant. Is the total spend field marked as required? Because "null + 5 = exception"
But anyway - to fix your problem you need something like that in the test.
#isTest
public static void updatecard(){
Card__c = new Card__c(total_spend__c = 100);
insert c;
UpdateMyCard.updateCard(200);
c = [SELECT total_spend__c FROM Card__c WHERE Id = :c.Id];
System.assertEquals(300, c.total_spend__c);
}

How to write unit test for spring cloud stream function based method?

When I try to test a spring cloud stream function based method, it always happens NullPointerException about InputDestination.
I have two questions:
It's hard for me to know how to write UT from the official doc. official test doc
Besides, how to write integration Test if test file has some dependencies. It seems create a new context and always has NoSuchBeanDefination error.
I have tried as flow, but the context can not find some dependency beans.
#Test
public void sampleTest() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(
MyTestConfiguration.class))
.run("--spring.cloud.function.definition=uppercase")) {
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
source.send(new GenericMessage<byte[]>("hello".getBytes()));
assertThat(target.receive().getPayload()).isEqualTo("HELLO".getBytes());
}
}
So I just want to write UT, but still have NPE.
Here is my code.
#Bean
public Function<Message<List<DemoBean>>, Message<DemoBean>> findFirstBean( ){
return message -> {
List<DemoBean> demoBeans = message.getPayload();
return MessageBuilder.withPayload(demoBeans.get( 0 )).build();
};
}
Here is my test.
#SpringBootTest
#ActiveProfiles(profiles = "local")
#Import({ TestChannelBinderConfiguration.class})
class FunctionDemoTest {
#Autowired
private InputDestination inputDestination;
#Autowired
private OutputDestination outputDestination;
private FunctionDemo functionDemo;
// some dependency need to mock
private DemoService demoService;
#BeforeEach
void setUp() {
demoService = Mockito.mock( DemoService.class );
functionDemo = new FunctionDemo( demoService);
}
#Test
public void findFirstBeanTest() {
DemoBean demoBean = new DemoBean();
demoBean.setName("Howard");
demoBean.setAge( 1 );
DemoBean demoBean1 = new DemoBean();
demoBean1.setName("Frank");
demoBean1.setAge( 2 );
List<DemoBean> demoBeanList = new ArrayList<>();
demoBeanList.add( demoBean );
demoBeanList.add( demoBean1 );
Message<List<DemoBean>> inputMessage = MessageBuilder.withPayload(demoBeanList).build();
inputDestination.send(inputMessage,"findFirstBean-in-0");
Assertions.assertNotNull( outputDestination.receive( 10000, "findFirstBean-out-0") );
}
}
Here is error:
java.lang.NullPointerException: while trying to invoke the method org.springframework.messaging.SubscribableChannel.send(org.springframework.messaging.Message) of a null object returned from org.springframework.cloud.stream.binder.test.InputDestination.getChannelByName(java.lang.String)
at org.springframework.cloud.stream.binder.test.InputDestination.send(InputDestination.java:89)
at com.successfactors.caf.listener.FunctionDemoTest.raePdrResultProcessor(FunctionDemoTest.java:82)
Well, I know the root cause of NPE.
Message<byte[]> receive(long timeout, String bindingName)
It seems should be destinationName instead of bindingName in source code.
Any other answers would be appreciated.

Junit error - No value present or no such element

testclass.java
#Test
public void testgetDictionaryValueListById() {
DictionaryValue dictionaryValue = new DictionaryValue();
dictionaryValue.setId(1);
dictionaryValue.setValueName("Test Dictionary Value");
dictionaryValue.setValueKey("12345678");
dictionaryValue.setStatus("Active");
dictionaryValue.setCreatedOn(new Date());
dictionaryValue.setUpdatedOn(new Date());
Mockito.when(dictionaryValueRepo.findById(1).get()).thenReturn(dictionaryValue);
assertThat(dictionaryService.getDictionaryValueListById(1)).isEqualTo(dictionaryValue);
}
Service.java
public DictionaryValue getDictionaryValueListById(int id) {
return dictionaryValueRepo.findById(id).get();
}
Repo.java
#Repository
public interface DictionaryValueRepo extends JpaRepository<DictionaryValue, Integer> {
}
I am getting no such value present again and again on executing test case in testclass.java. I don't know why? but when I am running my service method from the controller it is working as expected - fetching records from the database but not working in a test case.
Your test should be like this and please check out the naming. You need to Mock the step findId() befor the `get().
#InjectMocks
Service cut;
#Mock
DictionaryValueRepo dictionaryValueRepoMock;
// Can skipped by adding a #RunWith... on Testclass
#Before
public init() {
Mockito.initMocks(this);
}
#Test
public void testgetDictionaryValueListById() {
// Prepare Data
final int testId = 1;
DictionaryValue dictionaryValue = new DictionaryValue();
dictionaryValue.setId(testId);
dictionaryValue.setValueName("Test Dictionary Value");
dictionaryValue.setValueKey("12345678");
dictionaryValue.setStatus("Active");
dictionaryValue.setCreatedOn(new Date());
dictionaryValue.setUpdatedOn(new Date());
// config mocking
Mockito.when(dictionaryValueRepo.findById(testId)).thenReturn(<VALUE>);
Mockito.when(dictionaryValueRepo.findById(testId).get()).thenReturn(dictionaryValue);
// Call yout method for Testing
cut.getDictionaryValueListById(testId);
// verifies (if wanted) + assertions....
}
I concur with LenglBoy, so the right answer should be given to him.
The thing you need to be careful is what "VALUE" means in this line:
Mockito.when(dictionaryValueRepo.findById(testId)).thenReturn(VALUE);
The findById returns an Optional, so that is what you should build and pass to Mockito. Something like this:
Mockito.when(dictionaryValueRepo.findById(testId))
.thenReturn(Optional.ofNullable(dictionaryValue));
And for a scenario where the id does not exists in BD, passing Optional.empty() should be good enough.

ASP.Net Looking for guidance how to unit test code for MVC action

apologized to post this question here but i am in problem suddenly because i need to write unit test code for action where i am not good.
i am bit familiar with asp.net mvc. before i never write unit test code for action rather i manually test the action. now i want to know the art of writing unit test code for my action. so i read couple of article on unit test but notice all article share very basic idea about to write unit test code for action method in mvc controller but i am not being able to write unit test code for my action. so here i am pasting my one sample controller and their actions. so anyone please share knowledge how to write unit test code for my action methods below. if possible discuss with code sample or good hint which enable to write unit test code in VS2013 and MVC version 5.
here is my code
public class StudentController : Controller
{
private StudentRepository _Studentdata;
private StateRepository _Statedata;
private CityRepository _Citydata;
public StudentController()
{
_Studentdata = new StudentRepository(System.Configuration.ConfigurationManager.ConnectionStrings["StudentDBContext"].ConnectionString);
_Statedata = new StateRepository(System.Configuration.ConfigurationManager.ConnectionStrings["StudentDBContext"].ConnectionString);
_Citydata = new CityRepository(System.Configuration.ConfigurationManager.ConnectionStrings["StudentDBContext"].ConnectionString);
//_Studentdata = new StudentRepository(System.Configuration.ConfigurationManager.ConnectionStrings["StudentSQLDBContext"].ConnectionString);
//_Statedata = new StateRepository(System.Configuration.ConfigurationManager.ConnectionStrings["StudentSQLDBContext"].ConnectionString);
//_Citydata = new CityRepository(System.Configuration.ConfigurationManager.ConnectionStrings["StudentSQLDBContext"].ConnectionString);
}
// GET: Stuent
public ActionResult List(StudentListViewModel oSVm)
{
if (Request.IsAjaxRequest())
System.Threading.Thread.Sleep(1000); // just simulate delay of one second
StudentListViewModel SVm = new StudentListViewModel();
SVm.SetUpParams(oSVm);
SVm.Students = _Studentdata.GetStudents(oSVm.page, oSVm.PageSize, oSVm.sort, oSVm.sortdir).ToList();
SVm.States = _Statedata.GetAll().ToList();
SVm.Cities = _Citydata.GetAll().ToList();
SVm.RowCount = _Studentdata.DataCounter;
return View("ListStudents",SVm);
}
[HttpPost]
public ActionResult UpdateStudents(StudentListViewModel oSVm, string Action)
{
if (Request.IsAjaxRequest())
System.Threading.Thread.Sleep(1000); // just simulate delay of one second
StudentListViewModel SVm = new StudentListViewModel();
SVm.SetUpParams(oSVm);
if (Action == "UPDATE")
{
SVm.Students = _Studentdata.SaveXML(new List<Student>(oSVm.Students).ToXml("Students"),
oSVm.page, oSVm.PageSize, oSVm.sort, oSVm.sortdir).ToList();
}
else if (Action == "DELETE")
{
SVm.Students = _Studentdata.Delete(oSVm.Students[0].ID,
oSVm.page, oSVm.PageSize, oSVm.sort, oSVm.sortdir).ToList();
}
SVm.States = _Statedata.GetAll().ToList();
SVm.Cities = _Citydata.GetAll().ToList();
SVm.RowCount = _Studentdata.DataCounter;
return PartialView("_StudentGrid", SVm);
}
[HttpPost]
public ActionResult RefreshStudents(StudentListViewModel oSVm)
{
if (Request.IsAjaxRequest())
System.Threading.Thread.Sleep(1000); // just simulate delay of one second
StudentListViewModel SVm = new StudentListViewModel();
SVm.SetUpParams(oSVm);
SVm.Students = _Studentdata.GetStudents(oSVm.page, oSVm.PageSize, oSVm.sort, oSVm.sortdir).ToList();
SVm.States = _Statedata.GetAll().ToList();
SVm.Cities = _Citydata.GetAll().ToList();
SVm.RowCount = _Studentdata.DataCounter;
return PartialView("_StudentGrid", SVm);
}
[HttpGet]
public JsonResult GetCityName(int StateID)
{
if (Request.IsAjaxRequest())
System.Threading.Thread.Sleep(1000); // just simulate delay of one second
return Json(new {CityList =_Citydata.GetCityByStateId(StateID)} , JsonRequestBehavior.AllowGet);
}
}
Thanks

Iterate over the list of activities based on the input provided using AWS SWF

I have two servers(EC2 instances). In one server(server 1) i have 5 Batch and on another(server 2) i have 6 Batch. I wrapped each batch into activities and the work flow implementation class is given below. I want to iterate over the activities(entire activities, including server 1 and 2) based on the give execution date. For example, if the date is lesser than the current date then, execute all the activities of both server 1 and 2 starting from the given date up to the current date. If the execution date is equal to current date then, execute all the activities of both server 1 and 2 for current date. Also, if any of the activity for a day throws any exception then, don't execute the activities for the next day(<=current date).
public class JobWorkflowImpl implements JobWorkflow{
private DecisionContextProvider contextProvider
= new DecisionContextProviderImpl();
private WorkflowClock clock
= contextProvider.getDecisionContext().getWorkflowClock();
private BS1JobActivitiesClient bs1ActivitiesClient
= new BS1JobActivitiesClientImpl();
private BS2JobActivitiesClient bs2ActivitiesClient
= new BS2JobActivitiesClientImpl();
#Override
public void executeJob(Date exedate) {
Date today = new Date(clock.currentTimeMillis());
Date toProcess = exedate;
// All date manipulations are pseudocode here as I'm lazy
// to look up the real ones.
Promise<Void> previousDateDone = null;
while(toProcess <= today) {
// Create chain of executeJobForExactDate
// linked by previousDateDone to ensure that they are executed sequentially.
// null Promise is treated as ready promise by the framework.
previousDateDone = executeJobForExactDate(toProcess, previousDateDone);
toProcess.addDay(1);
}
}
Promise<Void> void executeJobForExactDate(Date date, Promise<Void> previous) {
Settable<Integer> firstServerDone = new Settable<Integer>();
Settable<Integer> secondServerDone = new Settable<Integer>();
Settable<Integer> resultODLSLBs1 = new Settable<Integer>();
//TODO Iterate over the activities
new TryCatchFinally(previous){
#Override
protected void doTry(){
Promise<Integer> resultFARBs1 = bs1ActivitiesClient.executecommand1(date);
Promise<Integer> resultUAMLFBs1 = bs1ActivitiesClient.executecommand2(date, resultFARBs1);
Promise<Integer> resultLLPBs1 = bs1ActivitiesClient.executecommand3(date, resultUAMLFBs1);
Promise<Integer> resultODLDLBs1 = bs1ActivitiesClient.executecommand4(date, resultLLPBs1);
// Chain links result of the activity execution
// to an aready existing Settable.
resultODLSLBs1.chain(bs1ActivitiesClient.executecommand5(date, resultODLDLBs1));
}
#Override
protected void doCatch(Throwable e){
throw new MyException("Failed");
}
#Override
protected void doFinally() throws Throwable {
firstServerDone.set(null);
}
};
new TryCatchFinally(previous){
#Override
protected void doTry() {
Promise<Integer> resultFARBs2 = bs2ActivitiesClient.executecommand1(date);
Promise<Integer> resultUAMLFBs2 = bs2ActivitiesClient.executecommand2(date, resultFARBs2);
Promise<Integer> resultLLPBs2 = bs2ActivitiesClient.executecommand3(date, resultUAMLFBs2);
Promise<Integer> resultODLDLBs2 = bs2ActivitiesClient.executecommand4(date, resultLLPBs2);
Promise<Integer> resultODLSLBs2 = bs2ActivitiesClient.executecommand5(date, resultODLDLBs2, resultODLSLBs1);
bs2ActivitiesClient.executecommand6(date, resultODLSLBs2);
}
#Override
protected void doCatch(Throwable e){
throw new MyException("Failed");
}
#Override
protected void doFinally(){
secondServerDone.set(null);
}
};
// AndPromise is done when all of its constructor parameters are done.
// I decided to consider the date processing done when both
// TryCatchFinallies are done. You can implement more complex logic depending on
// the business requirements. One option is to wrap both TryCatcFinallies
// in another TryCatchFinally.
return new AndPromise(firstServerDone, secondServerDone);
}
}
The problem is that, if any activity of server 1 throws any exception then, it is cancelling the all the activity that have not started for both server 1 and server 2. But I want only the activity that have not executed within a server should get cancelled as its own server activity has failed, the other server should continue as far as possible(i.e. the place up to which it is dependent).
The tricky part is that the Flow Framework requires that you use the Clock that it provides through the decision context. Otherwise it is not going to function correctly. The rest is just asynchronous Java programming.
public class JobWorkflowImpl implements JobWorkflow{
private DecisionContextProvider contextProvider
= new DecisionContextProviderImpl();
private WorkflowClock clock
= contextProvider.getDecisionContext().getWorkflowClock();
private BS1JobActivitiesClient bs1ActivitiesClient
= new BS1JobActivitiesClientImpl();
private BS2JobActivitiesClient bs2ActivitiesClient
= new BS2JobActivitiesClientImpl();
#Override
public void executeJob(Date exedate) {
Date today = new Date(clock.currentTimeMillis());
Date toProcess = exedate;
// All date manipulations are pseudocode here as I'm lazy
// to look up the real ones.
Promise<Void> previousDateDone = null;
while(toProcess <= today) {
// Create chain of executeJobForExactDate
// linked by previousDateDone to ensure that they are executed sequentially.
// null Promise is treated as ready promise by the framework.
previousDateDone = executeJobForExactDate(toProcess, previousDateDone);
toProcess.addDay(1);
}
}
Promise<Void> void executeJobForExactDate(Date date, Promise<Void> previous) {
Settable<Integer> firstServerDone = new Settable<Integer>();
Settable<Integer> secondServerDone = new Settable<Integer>();
Settable<Integer> resultODLSLBs1 = new Settable<Integer>();
//TODO Iterate over the activities
new TryCatchFinally(previous){
#Override
protected void doTry(){
Promise<Integer> resultFARBs1 = bs1ActivitiesClient.executecommand1(date);
Promise<Integer> resultUAMLFBs1 = bs1ActivitiesClient.executecommand2(date, resultFARBs1);
Promise<Integer> resultLLPBs1 = bs1ActivitiesClient.executecommand3(date, resultUAMLFBs1);
Promise<Integer> resultODLDLBs1 = bs1ActivitiesClient.executecommand4(date, resultLLPBs1);
// Chain links result of the activity execution
// to an aready existing Settable.
resultODLSLBs1.chain(bs1ActivitiesClient.executecommand5(date, resultODLDLBs1));
}
#Override
protected void doCatch(Throwable e){
System.out.println("Failed to execute BS1 daily job");
}
#Override
protected void doFinally() throws Throwable {
firstServerDone.set(null);
}
};
new TryCatchFinally(previous){
#Override
protected void doTry() {
Promise<Integer> resultFARBs2 = bs2ActivitiesClient.executecommand1(date);
Promise<Integer> resultUAMLFBs2 = bs2ActivitiesClient.executecommand2(date, resultFARBs2);
Promise<Integer> resultLLPBs2 = bs2ActivitiesClient.executecommand3(date, resultUAMLFBs2);
Promise<Integer> resultODLDLBs2 = bs2ActivitiesClient.executecommand4(date, resultLLPBs2);
Promise<Integer> resultODLSLBs2 = bs2ActivitiesClient.executecommand5(date, resultODLDLBs2, resultODLSLBs1);
bs2ActivitiesClient.executecommand6(date, resultODLSLBs2);
}
#Override
protected void doCatch(Throwable e){
System.out.println("Failed to execute BS2 daily job");
}
#Override
protected void doFinally(){
secondServerDone.set(null);
}
};
// AndPromise is done when all of its constructor parameters are done.
// I decided to consider the date processing done when both
// TryCatchFinallies are done. You can implement more complex logic depending on
// the business requirements. One option is to wrap both TryCatcFinallies
// in another TryCatchFinally.
return new AndPromise(firstServerDone, secondServerDone);
}
}