Unit test and code coverage on EventHandlers - c#

I'm trying to do a unit test on the eventHandler in the class and I'm not exactly sure how to get valid data to put in the tests. Thanks in advance!
public class BriefAssociation
{
public static event EventHandler<AssociationEventArgs> BriefAssociationChanged;
public static event EventHandler<AssociationEventArgs> BriefAssociationChangedEvent;
public static void OnBriefAssociationChanged(AssociationEventArgs e)
{
BriefAssociationChanged(null, e);
}
public static bool HasListener(EventHandler<AssociationEventArgs> TestCheck)
{
if ((BriefAssociationChangedEvent != null))
if ((BriefAssociationChangedEvent.GetInvocationList().Length > 0))
{
return true;
}
return false;
}
}
public class AssociationEventArgs
{
public int CustomerID;
}
CHANGES The following edit is for an error which is discussed in the comments
public class BriefAssociation
{
public static event EventHandler<AssociationEventArg> BriefAssociationChanged;
public static event EventHandler<AssociationEventArg> BriefAssociationChangedEvent;
public static void OnBriefAssociationChanged(AssociationEventArg e)
{
BriefAssociationChanged(null, e);
}
public static bool HasListener(EventHandler<AssociationEventArg> TestCheck)
{
if ((BriefAssociationChangedEvent != null))
if ((BriefAssociationChangedEvent.GetInvocationList().Length > 0))
{
return true;
}
return false;
}
}
public class AssociationEventArg
{
public int CustomerID;
}

For the second method "HasListener" I have a test that gives it a null value to test the if statement but I need to give it something that has a value of length grater than 0 to test the rest of the function. I hope it makes sense.
This is a simple test that might help
[Test]
public void should_raise_event()
{
BriefAssociation.BriefAssociationChangedEvent += BriefAssociationChanged;
bool result = BriefAssociation.HasListener(null);
Assert.True(result);
}
public void BriefAssociationChanged(Object obj, AssociationEventArgs associationEventArgs)
{ }

Here's all the test you need for the 1st method:
[Test]
public void OnBriefAssociationCHanged_ShouldRaiseBriefAssociationChangedEvent()
{
// Data
object resultSender = null;
AssociationEventArgs resultArgs = null;
AssociationEventArgs testArgs = new AssociationEventArgs();
// Setup
BriefAssociation.BriefAssociationChanged += (sender, args) =>
{
resultSender = sender;
resultArgs = args;
};
// Test
BriefAssociation.OnBriefAssociationChanged(testArgs);
// Analysis
Assert.IsNull(resultSender);
Assert.AreSame(resultArgs, testArgs);
}

Related

How can I stop a method being called more than once in 5 seconds?

I have this method:
public static async Task OpenPageAsync(string route)
{
await Shell.Current.GoToAsync(route, true);
}
If the method is called more than once in 5 seconds I would like the second call to be ignored. Has anyone come across a way to deal with this need?
Note that if it helps I do have access to create properities at the App level like this etc.
public partial class App : Application
{
public static int LastTapTime;
public static int TapTime;
In our project, we have created a 'MaxFrequencyUpdater' for exactly that cause.
Only difference: if within 5 seconds a new call comes in, it is delayed and executed after the 5 seconds interval.
namespace Utils
{
public class MaxFrequencyUpdater
{
private readonly WinformsExceptionHandler _exceptionHandler;
private readonly string _name;
private readonly int _millis;
private MethodInvoker _currentMethod;
private DateTime _lastExecuted = DateTime.MinValue;
private readonly object _updaterLockObject = new object();
public MaxFrequencyUpdater(string name, int maxFrequencyInMillis, WinformsExceptionHandler exceptionHandler)
{
_name = name;
_exceptionHandler = exceptionHandler;
_millis = maxFrequencyInMillis;
}
public void Update(MethodInvoker method)
{
lock (_updaterLockObject)
{
_currentMethod = method;
}
Task.Run(HandleWork);
}
private void HandleWork()
{
lock (_updaterLockObject)
{
// No longer bother, someone else handled it already
if (_currentMethod == null) return;
var now = DateTime.Now;
var delay = (int)(_millis - now.Subtract(_lastExecuted).TotalMilliseconds);
// Post-pone if too soon
if (delay > 0)
{
Task.Delay(delay).ContinueWith(HandleWork);
}
else
{
try
{
_currentMethod.Invoke();
}
catch (Exception e)
{
_exceptionHandler.HandleException(e);
}
_lastExecuted = now;
_currentMethod = null;
}
}
}
}
}
usage:
_maxFrequencyUpdater.Update(() =>
{
doSomething();
});

C# novice question about modifying outside variables inside a method

In the examples below I want to know a good way to make the bottom example function like the top example. I know that scope is the reason the bottom example does not work.
I am interested in doing this so I can tidy up the main body of my programs and eliminate some duplicated code.
namespace example_1
{
class Program
{
static void Main(string[] args)
{
int test = 5;
bool trigger = true;
if (trigger)
{
test++;
trigger = false;
}
}
}
}
namespace example_2
{
class Program
{
static void Main(string[] args)
{
int test = 5;
bool trigger = true;
if (trigger)
{
mod_test();
}
}
public static void mod_test()
{
test++;
trigger = false;
}
}
You can declare the properties outside of the methods, but still in the class :
class Program
{
// both of them are accessible within the class scope, but not outside
static int test = 5;
static bool trigger = true;
static void Main(string[] args)
{
if (trigger)
{
mod_test();
}
}
public static void mod_test()
{
test++;
trigger = false;
}
}
I think using a data container object is more suitable in this case. For example, in the following example, I wrapped the int and bool variables into a TestDataclass. This way you don't have to use global variables and still pass around the object reference for any kind of manipulation.
namespace example_3
{
class TestData
{
public bool Trigger { get; set; }
public int Test { get; set; }
}
class Program
{
static void Main(string[] args)
{
var testData = new TestData
{
Test = 5,
Trigger = true
};
if (testData.Trigger)
{
mod_test(testData);
}
}
public static void mod_test(TestData data)
{
data.Test++;
data.Trigger = false;
}
}
}

The script needs to Derive from MonoBehaviour, can not take parameters

I have project in Unity and also new to C#. Problem is that I got error The script needs to Derive from MonoBehaviour. I understand what does that mean but when I use MonoBehaviour I'm getting tons of Errors like this:
Errors in console
Will be glad if anyone can explain what am i doing wrong - thank you good people of stackoverflow!
Every script is connected to BaseWindow
namespace BlGame.View
{
public abstract class BaseWindow
{
protected Transform mRoot;
protected EScenesType mScenesType;
protected string mResName;
protected bool mResident;
protected bool mVisible = false;
public abstract void Init();
public abstract void Realse();
protected abstract void InitWidget();
protected abstract void RealseWidget();
protected abstract void OnAddListener();
protected abstract void OnRemoveListener();
public abstract void OnEnable();
public abstract void OnDisable();
public virtual void Update(float deltaTime) { }
public EScenesType GetScenseType()
{
return mScenesType;
}
public bool IsVisible() { return mVisible; }
public bool IsResident() { return mResident; }
public void Show()
{
if (mRoot == null)
{
if (Create())
{
InitWidget();
}
}
if (mRoot && mRoot.gameObject.activeSelf == false)
{
mRoot.gameObject.SetActive(true);
mVisible = true;
OnEnable();
OnAddListener();
}
}
public void Hide()
{
if (mRoot && mRoot.gameObject.activeSelf == true)
{
OnRemoveListener();
OnDisable();
if (mResident)
{
mRoot.gameObject.SetActive(false);
}
else
{
RealseWidget();
Destroy();
}
}
mVisible = false;
}
//预加载
public void PreLoad()
{
if (mRoot == null)
{
if (Create())
{
InitWidget();
}
}
}
//延时删除
public void DelayDestory()
{
if (mRoot)
{
RealseWidget();
Destroy();
}
}
private bool Create()
{
if (mRoot)
{
Debug.LogError("Window Create Error Exist!");
return false;
}
if (mResName == null || mResName == "")
{
Debug.LogError("Window Create Error ResName is empty!");
return false;
}
if (GameMethod.GetUiCamera.transform== null)
{
Debug.LogError("Window Create Error GetUiCamera is empty! WindowName = " + mResName);
return false;
}
GameObject obj = LoadUiResource.LoadRes(GameMethod.GetUiCamera.transform, mResName);
if (obj == null)
{
Debug.LogError("Window Create Error LoadRes WindowName = " + mResName);
return false;
}
mRoot = obj.transform;
mRoot.gameObject.SetActive(false);
return true;
}
//销毁窗体
protected void Destroy()
{
if (mRoot)
{
LoadUiResource.DestroyLoad(mRoot.gameObject);
mRoot = null;
}
}
public Transform GetRoot()
{
return mRoot;
}
}
}
Something like This:
public class UIGuideWindow : BaseWindow
{
public UIGuideWindow()
{
//mScenesType = EScenesType.EST_Login;
//mResName = GameConstDefine.UIGuideRestPath;
//mResident = false;
}
Unity Update Function cannot have any paramaters like this : Update(float deltaTime), this is unity not unreal engine:))
To fix this, Remove float deltaTime , and instead use Time.deltaTime inside the function implementation itself

Returning a function if specific conditions are not followed

Is it possible to not execute functionC if conditions are not followed in functionA?
public void functionA()
{
if(!specificCondition)
{
return;
}
}
public void functionB()
{
functionA();/*Conditions did not meet so i no longer want the next
function to execute anymore */
functionC();
}
public void functionC()
{
Console.WriteLine("OK");
}
Sure, check the condition before you call them:
public void functionB()
{
if(specificCondition)
functionA();
if(specificCondition)
functionC();
}
Another option is to return a bool which you could check before you call the next method.
Just return a bool from functionA
public bool functionA()
{
if(!specificCondition)
return true;
return false;
}
public void functionB()
{
if(!functionA())
functionC();
}
public void functionC()
{
Console.WriteLine("OK");
}
I should make clear that returning a boolean condition from the functions is the correct way to proceed. If, however, you find yourself in a situation where you can't change either the parameters or the return type of the other methods, you can use a class-level variable.
class myClass
{
var specificCondition = false;
public void functionA()
{
var resultOfThisMethod = specificCondition;
/*do stuff
*
*
*/
if(resultOfThisMethod != testedcondition)
specificCondition = false;
}
public void functionB()
{
functionA();/*Conditions did not meet so i no longer want the next
function to execute anymore */
specificCondition ? functionC() : return;
}
public void functionC()
{
Console.WriteLine("OK");
}
}
I hope this Code will help you... In this we can get
specificCondition from functionA as ref and used in functionB to
take decision to functionC.
Using Ref
public void functionA(ref bool cond)
{
cond = specificCondition;
if (!specificCondition)
{
return;
}
}
public void functionB()
{
bool cond = false;
functionA(ref cond);
if (cond)
{
functionC();
}
}
public void functionC()
{
Console.WriteLine("OK");
}
Using Out.
public static void functionA(out bool cond)
{
bool specificCondition = true;
cond = specificCondition;
if (!specificCondition)
{
return;
}
}
public static void functionB()
{
bool cond;
functionA(out cond);
if (cond)
{
functionC();
}
}
public static void functionC()
{
Console.WriteLine("OK");
}

delegate or reflection?

I have a class with a method in which a string will be passed. That method will do some things to that string and it then passes the string to a certain object which can do other things with the string.
So it basically looks like this:
class Main
{
public Main()
{
strClass str = new strClass(this);
}
public function handler ( )
{
console.log("No string is passed yet, but this method is called from receiveData()");
}
}
class strClass
{
object handler;
public strClass ( handler )
{
// save the object
this.handler = handler;
}
public receiveData ( string str )
{
// This method does some stuff with the string
// And it then passes it on to the supplied object (handler) which will do
// the rest of the processing
// I'm calling the "handler" method in the object which got passed in the
// constructor
Type thisType = this.handler.GetType();
MethodInfo theMethod = thisType.GetMethod("handler");
theMethod.Invoke(this.handler, null);
}
}
Now this code works good, with the reflection stuff. But i was wondering, shouldn't this be possible (and maybe even better?) with delegates?? If so, how can i implement this by using a delegate instead?
Couldn't you use interfaces instead:
interface IStringHandler {
void HandleString(string s);
}
class strClass
{
IStringHandler handler = null;
public strClass(IStringHandler handler)
{
this.handler = handler;
}
public void ReceiveData(string s)
{
handler.HandleString(s);
}
}
class Main : IStringHandler
{
// Your code
}
A delegate is a better option here.
class Main
{
public Main()
{
StrClass str = new StrClass(this.Handler);
}
public void Handler ( )
{
//called from recieve data
}
}
class StrClass
{
readonly Action _handler;
public StrClass ( Action callback)
{
// save the object
this._handler = callback;
}
public void receiveData( string str )
{
this._handler();
}
}
You can do it with an Action like this:
class Main
{
public Main()
{
strClass str = new strClass(newString =>
{
console.log("This string I got back: " + newString);
});
}
}
class strClass
{
Action<string> callback;
public strClass (Action<string> callback)
{
// save the action
this.callback = callback;
}
public receiveData ( string str )
{
// Do something with the string
callback(str);
}
}
Even nicer than using delegates whould be using the
Chain of Responsibility design pattern, which does exactly what you need :).
Firstly, if you must call an unknown method by name, use dynamic - it is heavily optimised for this (although still not a great idea):
((dynamic)handler).handler(); // but please don't use this! see below
However, I would instead look at either an Action<string> (or maybe Func<string,string>), or an interface with a known method on it.
Basically, you want to change how your StrClass object react to data begin received. Sounds like events to me.
something like this, where you have handling methods both in the Main and in a generic HandlerObject:
class StrClass : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = null;
public void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
PropertyChanged(this, e);
}
private string receivedString;
public string ReceivedString
{
get;
set
{
string oldStr = receivedString;
receivedString = value;
PropertyChanged(receivedString, new PropertyChangedEventArgs("ReceivedString"));
}
}
public void receiveData(string str)
{
//event fires here
ReceivedString = str;
}
}
class HandlerObject
{
public void HandlerMethod1(string s)
{
//magic
}
public void HandlerMethod2(string s)
{
//different kind of magic
}
}
class Program
{
static void HandlerMethod3(string s)
{
//another kind of magic!
}
static void Main(string[] args)
{
StrClass class1 = new StrClass();
StrClass class2 = new StrClass();
StrClass class3 = new StrClass();
HandlerObject handler = new HandlerObject();
class1.PropertyChanged += (s, e) => { handler.HandlerMethod1(s.ToString()); };
class2.PropertyChanged += (s, e) => { handler.HandlerMethod2(s.ToString()); };
class3.PropertyChanged += (s, e) => { HandlerMethod3(s.ToString()); };
}
}

Categories

Resources