MOQ 'TestMethod(Action<int> callback)' and be able to 'call' callback - c#

Oook,
I'm wanting to mock a callback that I know my service will call. For example:
public interface ITestMe { void TestMethod(Action<int> callback); }
In the application, when calling 'TestMethod' I would pass the callback method to hit after it has run, which will do something based on the parameters. Typically, in this case it's used like this:
...
testMe.TestMethod(
(ret) =>
{
if(ret < 0)
AddToErrorCollection(ret);
else
AddToSuccessCollection(ret);
}
);
What I'd like to do in MOQ is call that anonymous method with a range of values i.e. something like:
myMock.Setup(m => m.TestMethod(It.IsAny<Action<int>>())).... //Call that action!!??
Is there anyway to do that?
Is this even the correct way to do it?

try this:
myMock.Setup(m => m.TestMethod(It.IsAny<Action<int>>())).Callback<Action<int>>((action) => action(4));
although this seems a rather convoluted way to essentially test your callback method. Why not test it directly?

Related

Test if method in ClassA has been called from another method in ClassA

It is possible to test if a method has been called using Moq and dependency injection. However, is it possible to test if one method in a class calls another within the same class?
For example, I want to test that if I log a certain exception, that an information message is logged as well.
The method is:
public void Error(string message, Exception exception, long logId = 0)
{
var int32 = (int)logId;
Info("Id was converted to an int so that it would fit in the log: " + logId, int32);
Error(message, exception, int32);
}
This was my attempt at unit testing it. The test fails, is there any way that it can it be done?
void logging_an_error_with_a_long_id_also_logs_info()
{
var mock = new Mock<ILogger>();
var testedClass = new Logger();
var counter = 0;
testedClass.Error("test" + counter++, new Exception("test" + counter), Int64.MaxValue);
mock.Verify(m => m.Info(It.IsAny<string>(), It.IsAny<int>()));
}
Since the Info and Error methods are in the same class (ClassA), I don't believe I can pass ClassA as a dependency into ClassA. So does it not need tested?
The best you're going to be able to do is to make Info virtual. This will allow you to create a Mock<Logger>, set CallBase = true, and verify that Info was called.
var mock = new Mock<Logger>
{
CallBase = true
};
mock.Object.Error("test" + counter++, new Exception("test" + counter), Int64.MaxValue);
mock.Verify(m => m.Info(It.IsAny<string>(), It.IsAny<int>()));
This way, you're still calling the actual implementation of Error, but you've used Moq to verify the Info method was called.
It feels like you're trying to test the wrong thing. It's not really important that the Info method on your class is called from the Error method, what's important is that the behaviour of the Info method occurs. How it happens is an implementation detail of the class.
If I had a math class with two functions:
public int Mult(int x, int y) {
return x*y;
}
public int Sqr(int x) {
return Mult(x,y);
}
I wouldn't test that calling Sqr called out to the Mult function, I would test Sqr(4)==16. It doesn't matter if that calculation takes place in the Sqr method, or in another method of the class.
Whilst #Andrew's solution is probably what you're after, mocking the class you're testing tends to lead to tightly coupled, brittle tests.
If it's impractical to test the call by observing it's side effects, then it may be a sign that the implementation could use a bit of refactoring.

RhinoMocks mock method without return

I am new to mocking. I need to mock method (it doesn't have return value). I cannot find any examples of how to mock a method. I need to mock ITempDa.Import method.
var stub = MockRepository.GenerateStub<ITempDA>();
stub.Stub(x => x.Import(param1)). ???
public void MockedImport() {
// some processing here
}
ITempDa.Import should be mocked and instead some internal method "MockedImport" should be called.
As #JamesLucas said you don't need to use Return() method(you should use this method only when your method is not void).
In this case you should use the Do() method:
var stub = MockRepository.GenerateStub<ITempDA>();
stub.Stub(x => x.Import(Arg<object>.Is.Anything))
.Do(new Action<object>(o => MockedImport()));
or if MockedImport ths same arguments as Import:
stub.Stub(x => x.Import(Arg<object>.Is.Anything))
.Do(new Action<object>(MockedImport);
You should use WhenCalled method when the method under test called your fake and you want to intercept the execution(execute something + change return value/change arguments/do additional steps and etc...). Another reason to use Do instead of WhenCalled is, your code become more readable.
Usually I do not recommend to use IgnoreArguments method. The reason is quite simple, you test the method behaviour. When something violate the method behaviour then the test should fail. IgnoreArguments easily hide things. However, if the calling parameters aren't important do:
stub.Stub(x => x.Import(null))
.IgnoreArguments()
.Do(new Action<object>(o => MockedImport()));
In this instance you don't need a Return() call as the method is void returning. If you want to intercept the call and perform some logic on the mocked operation then use WhenCalled. In this scenario it's also worht just ignoring the arguments in the Stub and handling everything in the WhenCalled expression. e.g.
var stub = MockRepository.GenerateStub<ITempDA>();
stub.Stub(x => x.Import(null))
.IgnoreArguments()
.WhenCalled(invocation =>
{
var arg = invocation.Arguments[0] as ...;
// etc
});

how to mock the if condition that checks the data in database with moq

I am trying to mock a method that first checks if the data is present in database, if not then it calls the save method. How do i mock the if condition?
Code is like this
public MyCode AddMyCode(MyCode myCode)
{
int workingUnitId = _sessionManager.CurrentUser.WorkingUnit.Id;
if (!_db.MyCodes.Any(d => d.Code == myCode.Code && d.UnitId == this.CurrentUserParentUnitId))
{
_db.MyCodes.Add(myCode);
SaveMyCode();
return myCode;
}
return myCode;
}
you should use interfaces to decouple database access code (EF here) and your business logic.
this way you can test your logic without need for a real database.
a good tutorial could be this : http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
You can mock your data base call by setting up some dummy data into MyCodes and see whether the rest of the code is working fine.
Updated:
include a static method like this:
public static Mock<ControllerContext> MockSession()
{
var controllerContext = new Mock<ControllerContext>();
controllerContext.Setup(X => X.HttpContext.Session["UserName"]).Returns("Avinash");
return controllerContext;
}
Then you can do:
In your test method,
Use the above static method to mock the session:
target.ControllerContext = MockSession().Object;
This will mock the session. The above example is from asp.net MVC Prespective. I am not sure how to do it with normal webforms.
You can try to implement it for webforms also based on above.

Using Delegate to execute code at the method entry and exit

I have code that does very repetitive things such as logging the method entry and exit. In between, I execute some business logic. Is there a way I could handle that with a Delegate?
Here is what I have so far. However, it is really restrictive due to the func parameters I must passing. Anybody has a better idea?
Func<Func<int>, int> logAction = new Func<Func<int>, int>(func =>
{
try
{
Console.WriteLine("Logging...");
return func();
}
finally
{
Console.WriteLine("End Logging...");
}
});
Postsharp is perfect for this- it is an Aspect Orientated Programming library that features compile time weaving, so it wont impact on performance like run time weaving. This probably doesn't explain much if your new to AOP but basically, it will allow you to declare logging on a method like this:
<Logging> //apply an aspect that will log entrance/exit of method
void MyMethod(params)
{
//do something that might throw an exception (or not)
}
For an example (and source code) on using postsharp for logging, see http://www.sharpcrafters.com/solutions/logging
It seems that one of the AOP frameworks could solve your issue.
private void LogAction(string title, Action action)
{
Logger.Write(string.Format("Entering %0", title));
action();
Logger.Write(string.Format("Leaving %0", title));
}
Sample usage with no return value:
LogAction("DoSomething", () => DoSomething());
Sample usage with return value:
int intResult = 0;
LogAction("Square", () => intResult = Square(4, 4));
The easiest way to do this is to wrap everything inside of an Action and then just execute that in a method
public void log(Action methodToExecute)
{
try
{
Console.WriteLine("Logging...");
methodToExecute();
}
finally
{
Console.WriteLine("End Logging...");
}
}
Then call it creating a generic action for your function
//no return
log(() => yourFunciton(optionalParmeters));
//return to something
log(() => someVar = yourFunction(optionalParameters));

C# Is there a way to create functions that accept anonymous function code as argument?

I would like to do something like
NameOfTheMethod(parameters){
// Code...
}
There's using, foreach, for, etc. that are already built-in, but I don't know if creating something similar is even possible. Is it?
The reason why I ask this is because sometimes that there are many different pieces of code that are wrapped by basically the same code (examples are opening a connection to the database, creating the command, settings the datareader, testing if an element exists in cache and, if not, go get it, otherwise get it from cache, etc.)
Yes, you can take a delegate instance as an argument:
void MyMethod(Func<Arg1Type, Arg2Type, ReturnType> worker) {
Arg1Type val1 = something;
Arg2Type val2 = somethingelse;
ReturnType retVal = worker(something, somethingelse);
// ...
}
You'd call it like:
MyMethod((arg1, arg2) => {
// do something here with the arguments
return result;
});

Categories

Resources