How to set counter in main flow from called delegate function

Suraj 1 Reputation point
2021-04-02T16:01:17.01+00:00

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;


    //}
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,232 questions
0 comments No comments
{count} votes

6 answers

Sort by: Most helpful
  1. Karen Payne MVP 35,036 Reputation points
    2021-04-02T17:18:32.463+00:00

    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

    0 comments No comments

  2. Suraj 1 Reputation point
    2021-04-02T18:05:17.153+00:00

    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

    0 comments No comments

  3. Viorel 112.1K Reputation points
    2021-04-02T18:17:17.547+00:00

    Maybe add a new event — InitLockDown — like this:

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

    Your setCounter will invoke this event.

    0 comments No comments

  4. Suraj 1 Reputation point
    2021-04-02T18:21:41.12+00:00

    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);
     }
    
    0 comments No comments

  5. Karen Payne MVP 35,036 Reputation points
    2021-04-02T19:32:18.14+00:00

    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

    0 comments No comments