question

Suraj-5756 avatar image
0 Votes"
Suraj-5756 asked Suraj-5756 commented

How to set counter in main flow from called delegate function

Hi,

Am having some trouble getting this going - here's the code. Need the delegate function call triggered in StartLockDown() to be able to set the lockDownStartedCount in the code below. Not sure if this is possible. Thought to reach out.
[Test]
public void LockDownMethods_RaisingTheEvents()
{
int lockDownStartedCount = 0, lockDownEndedCount = 0;

         _lockDownManager.LockDownEnded += (sender, args) => lockDownEndedCount++;
         _lockDownManager.LockDownStarted += (sender, args) => lockDownStartedCount++;


         Assert.AreEqual(0, lockDownStartedCount);
         Assert.AreEqual(0, lockDownEndedCount);



         _lockDownManager.StartLockDown();
         Assert.AreEqual(1, lockDownStartedCount);
         Assert.AreEqual(0, lockDownEndedCount);


         _lockDownManager.StartLockDown();
         Assert.AreEqual(1, lockDownStartedCount);
         Assert.AreEqual(0, lockDownEndedCount);


         _lockDownManager.EndLockDown();
         Assert.AreEqual(1, lockDownStartedCount);
         Assert.AreEqual(1, lockDownEndedCount);

         _lockDownManager.EndLockDown();
         Assert.AreEqual(1, lockDownStartedCount);
         Assert.AreEqual(1, lockDownEndedCount);

         _lockDownManager.StartLockDown();
         Assert.AreEqual(2, lockDownStartedCount);
         Assert.AreEqual(1, lockDownEndedCount);
     }



Currently - I have the StartLockDown method in lockdownmanager method as

public void StartLockDown()
{

           LockDownStarted = setCounter();
         LockDownStarted.Invoke(this, EventArgs.Empty); // think something needs to change here - like pass the main counter value to setCounter - I tried deriving from EventArgs and adding an int field, that didn't work either
       }


public virtual void setCounter(object sender, EventArgs e)
//{
// this method is incorrect, something needs to happen here...
// Console.Write(" in setAccountLockdown----start####");

     //    //if (e.counter == 0)
     //    //    e.counter = 1;
            
            
     //}
dotnet-csharp
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

karenpayneoregon avatar image
0 Votes"
karenpayneoregon answered

Hopefully this is helpful.

The following should be testable in a unit test method. Note I have all code in one file where each class should be broken out into their own files. Note how the delegate/event are done using a class (WhatEver) as a argument to the delegate.

 namespace ConsoleApp1.Classes
 {
     class Class1
     {
         public delegate void OnProcessingCompleted(WhatEver sender);
         public static event OnProcessingCompleted OnProcessingCompletedEvent;
    
         public static void DoWork()
         {
             OnProcessingCompletedEvent?.Invoke(new WhatEver()
             {
                 StartLockDownCount = 1, 
                 EndLockDownCount = 10
             });
         }
     }
    
     public class WhatEver
     {
         public int StartLockDownCount { get; set; }
         public int EndLockDownCount { get; set; }
     }
    
     public class Caller
     {
         public Caller()
         {
             Class1.OnProcessingCompletedEvent += Class1OnOnProcessingCompletedEvent;
         }
    
         private void Class1OnOnProcessingCompletedEvent(WhatEver sender)
         {
             var startCount = sender.StartLockDownCount;
         }
     }
        
 }

And for completeness here is how I write unit test

84092-f1.png



f1.png (34.8 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Suraj-5756 avatar image
0 Votes"
Suraj-5756 answered

Hi Karen,

Thank you for the response. I think we might be missing one piece here, its not so much about as a lockdown counter. Rather it is getting the called delegate function to update a counter variable in the main calling code. Example - the main calling code has

_lockDownManager.LockDownStarted += (sender, args) => lockDownStartedCount++;

Assume value of lockDownStartedCount is 0.

Now when we call

lockDownManager.StartLockDown();
Assert.AreEqual(1, lockDownStartedCount); // this one will now return true since StartLockDown method invokes the delegate also increasing the value of lockDownStartedCount by 1 as per the definition above _lockDownManager.LockDownStarted += (sender, args) => lockDownStartedCount++;



public void StartLockDown()
{

        LockDownStarted = setCounter();
      LockDownStarted.Invoke(this, EventArgs.Empty); 
    }


public virtual void setCounter(object sender, EventArgs e)
//{
//Do something here
and then reset lockDownStartedCount back to zero

  //}


What we are trying to achieve is reset the value of lockDownStartedCount in the main calling code to 0 from setCounter().

Hope that helps to understand the issue.

Thanks

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Viorel-1 avatar image
0 Votes"
Viorel-1 answered

Maybe add a new event — InitLockDown — like this:

 lockDownManager.InitLockDown += (sender, args) => lockDownStartedCount = 0;

Your setCounter will invoke this event.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Suraj-5756 avatar image
0 Votes"
Suraj-5756 answered

Hi Viorel-1,

I think your solution would work. However, am asked not to modify the main calling code....as in the main [Test] method

[Test]
public void LockDownMethods_RaisingTheEvents()
{
int lockDownStartedCount = 0, lockDownEndedCount = 0;

      _lockDownManager.LockDownEnded += (sender, args) => lockDownEndedCount++;
      _lockDownManager.LockDownStarted += (sender, args) => lockDownStartedCount++;
      Assert.AreEqual(0, lockDownStartedCount);
      Assert.AreEqual(0, lockDownEndedCount);
      _lockDownManager.StartLockDown();
      Assert.AreEqual(1, lockDownStartedCount);
      Assert.AreEqual(0, lockDownEndedCount);
      _lockDownManager.StartLockDown();
      Assert.AreEqual(1, lockDownStartedCount);
      Assert.AreEqual(0, lockDownEndedCount);
      _lockDownManager.EndLockDown();
      Assert.AreEqual(1, lockDownStartedCount);
      Assert.AreEqual(1, lockDownEndedCount);
      _lockDownManager.EndLockDown();
      Assert.AreEqual(1, lockDownStartedCount);
      Assert.AreEqual(1, lockDownEndedCount);
      _lockDownManager.StartLockDown();
      Assert.AreEqual(2, lockDownStartedCount);
      Assert.AreEqual(1, lockDownEndedCount);
  }
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

karenpayneoregon avatar image
0 Votes"
karenpayneoregon answered

Look at the following which has a class project and a unit test project.

The code is a working conceptual test example that does not match up to your code but the point should be apparent

Test class

 using System;
 using System.Collections.Generic;
 using ManagerLibrary;
 using ManagerUnitTestProject.Base;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
    
 namespace ManagerUnitTestProject
 {
     [TestClass]
     public class UnitTest1 : TestBase
     {
         [TestInitialize]
         public  void Init()
         {
    
             if (TestContext.TestName == "TestMethod1")
             {
                 Example.OnProcessingCompletedEvent += OnProcessingCompletedEvent;
             }
                
         }
         /// <summary>
         /// Creates an new instance of TestContext used above
         /// </summary>
         /// <param name="testContext"></param>
         [ClassInitialize()]
         public static void MyClassInitialize(TestContext testContext)
         {
             TestResults = new List<TestContext>();
         }
         [TestMethod]
         public void TestMethod1()
         {
             var example = new Example() {StartValue = 1, EndValue = 10};
             example.DoWork();
    
             Assert.IsTrue(StarterValue == 1 && EnderValue == 10);
                
         }
         private void OnProcessingCompletedEvent(WhatEver sender)
         {
             StarterValue = sender.StartLockDownCount;
             EnderValue = sender.EndLockDownCount;
         }
     }
 }


Test base

 using System.Collections.Generic;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
    
 namespace ManagerUnitTestProject.Base
 {
     public class TestBase
     {
         protected TestContext TestContextInstance;
         public TestContext TestContext
         {
             get => TestContextInstance;
             set
             {
                 TestContextInstance = value;
                 TestResults.Add(TestContext);
             }
         }
    
         public static IList<TestContext> TestResults;
    
         public int StarterValue { get; set; }
         public int EnderValue { get; set; }
    
    
     }
 }

Class project
84026-f1.png



f1.png (24.0 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Suraj-5756 avatar image
0 Votes"
Suraj-5756 answered Suraj-5756 commented

Hi Karen,

Thank you for your response. I can see your solution working too. And you're right, it requires the Whatever class being passed from the main calling program and using this to set sender.startLockDown = <whatever value we want to>

and hopefully this should reflect in the main code.

I haven't tested this yet. There are a bunch of constraints that am forced to get the solution for. My Handler is a no param Event Handler so am not sure how this would work without a param for eventdata being passed to the delegate.

Maybe the question is flawed. I don't know. I was given this as a part of a test - maybe it does requires a parameter to be passed to the EventHandler/delegate.

Good to know though. This is new for me and I am learning reading all the comments on here.

Thank you all,
Suraj

· 4
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Not to solve your task but might be good to read the following.


1 Vote 1 ·

Thanks Karen, that looks like some great information on there. Shall certainly review whether it does/ doesn't solve this particular puzzle.

Thank you,

0 Votes 0 ·

Cool, and know that unit testing is a completely different ball of wax than when writing application code. When done right one learns to write their code via TDD. Older versions of Visual Studio had this

84135-generatefromusage.png

While later and current Visual Studio has less functionality but is still doable.


1 Vote 1 ·
Show more comments