Moq setup for interface with action/function argument - c#

I am trying to mock a call to a server and verify that the tested code called the correct method. Code structure is as follows:
public interface IServerAdapter
{
void CallServer(Action<IServerExposingToClient> methodToCall, out bool serverCalled);
object CallServer(Func<IServerExposingToClient, object> methodToCall, out bool serverCalled);
}
public interface IServerExposingToClient
{
Resource GetResource(string id);
void AddResource(Resource resource);
}
The code I'm testing accesses an implementation of IServerAdapter and calls IServerExposingToClient methods on the server. The reason for this is that we don't want to have to implement every single method (there are quite a lot of them) on the IServerExposingToClient in a class. Since this is then invoked on the proxy, it works quite well in our code.
Calling a method on the server is done like this:
_mainViewModel.ServerAdapter.CallServer(m => m.AddResource(resource), out serverCalled);
The problem now is testing and mocking. I need to assert that the method (AddResource) has been called on the server. The out serverCalled (problem 1) is to make sure the call has made it to the server so logic flows as it should for the caller.
When I use the following Moq setup, I can assert that some method has been called on the server:
Mock<IServerAdapter> serverAdapterMock = new Mock<IServerAdapter>();
bool serverCalled;
bool someMethodCalled = false;
serverAdapterMock.Setup(c => c.CallServer(It.IsAny<Action<IServerExposingToClient>>(), out serverCalled)).Callback(() => someMethodCalled = true);
// assign serverAdapterMock.Object to some property my code will use
// test code
Assert.IsTrue(someMethodCalled, "Should have called method on server.");
As the test says, I can assert that some method has been called on the server. The problem is that I don't know which method has been called. In some methods, the logic I want to test could take different paths depending on conditions, and for some scenarios, several paths might lead to a server call. Because of this, I need to know which method was called so I can have the correct asserts in my test (problem 2).
The variable serverCalled needs to be set to match a signature for the method call on the IServerAdapter mock. I would also very much like to be able to set that variable inside some callback or whatever which would let the logic of the code I'm testing flow the way it should (problem 1). Because of the way it works now, serverCalled will not be set by the mock setup.
The main problem is not knowing which method was called against the server. I've tried to use Match to check the name of the delegate method, but no sigar.
serverAdapterMock.Setup(c => c.CallServer(Match.Create<Action<IServerExposingToClient>>( x => IsAddResource(x)), out serverCalled)).Callback(() => someMethodCalled = true);
When IsAddResource is called, the function does not refer to AddResource, only where it was created and what argument it is called with.
Does anyone know how to check which method was called?
For the other problem with out serverCalled, you could argue that the void method could be bool instead, and that the other method could return null if we don't have a connection to the server (the last argument would be ambiguous as null could either mean object did not exist, or server was unavailable).
I would very much like suggestions for working out both problems.
Thanks in advance

Problem one:
As you've pointed out, a Callback here would be ideal. Unfortunately, because your method signature has a out parameter it currently cannot be intercepted by Moq. There's a post in the Moq forums that is similar to your concern. There's no indication that it will be addressed.
If you're open to changing your method signature, consider dropping the out parameter -- they're a bit of a smell anyway. Things would be a lot simpler if you just threw an exception when the server was not available. Getting that out of there (pun intended) would open your Callback to handle your second problem.
Problem two:
Consider changing your method signature to be Expression<Action<IServerExposingToClient>>. I realize there's a lot of angle brackets there, but an Expression is syntactically equivalent to Action<T> (you wouldn't have to change your calling code) and would allow your Callback to walk the code expression tree and get the name of your calling method.
You can get the name of the method using something like:
public string GetMethodName(Expression<Action<IServerExposingToClient>> exp)
{
return ((ExpressionMethodCall)exp.Body).Method.Name;
}
You now have enough arsenal to go after your mock. You can either write a callback that logs the names of method calls or you can write matchers to help define behavior when methods are called.
For example:
[Test]
public void WhenTheViewModelIsLoaded_TheSystem_ShouldRecordOneNewResource()
{
// arrange
var serverAdapterMock = new Mock<IServerAdapter>();
var subject = new SubjectUnderTest( serverAdapterMock.Object );
// act
subject.Initialize();
// assert
serverAdapterMock.Verify( c => c.CallServer( IsAddResource() ), Times.Exactly(1));
}
static Expression<Action<IServerExposedToClient>> IsAddResource()
{
return Match.Create<Expression<Action<IServerExposedToClient>>>(
exp => GetMethodName(exp) == "AddResource");
}

Related

Is using property getters for initialization (to avoid having to call methods in specific order) bad practice?

Suppose I have a class that provides some data to my application. Data initially comes from database, and I provide it through some methods that handle the whole database thing and present the result as a usable class instead of raw query result. This class has to do some setup (not complex) to make sure any method called can use the database (e.g. connect to database, make sure it contains some critical info, etc). So, were I to put it in a method (say, method Init(), that would handle checking for database, connecting to it, verifying that it does contain the info), I would have to make sure that this method is called before any other method.
So, I usually find that instead of doing this:
public class DataProvider
{
private SqlController controller;
public void Init()
{
controller = new SqlController();
controller.Init();
controller.ConnectToDataBase();
CheckForCriticalInfoInDatabase();
}
public Data GetData()
{
// get data from database (not actually going to use raw queries like that, just an example)
var queryResult = sqlController.RunQuery("SELECT something FROM SOME_TABLE");
// and present it as usable class
Data usefulData = QueryResultToUsefulData(queryResult);
return usefulData;
}
...
}
and then always making sure I call Init() before GetData(), i do something like
private SqlController _controller;
private SqlController controller
{
get
{
if (_controller == null)
{
_controller = new SqlController();
_controller.Init();
_controller.ConnectToDataBase();
CheckForCriticalInfoInDatabase();
}
return controller;
}
}
So, now i can be sure that i won't use an uninitialised SqlController, and I don't have to do that same null check in every method that uses it. However, I never noticed getters being used this way in other peoples' code.
Is there some pitfall I don't see? To me it looks like it's the same as lazy initialization, with the exception being that I use it not because the initialization is heavy or long, but because I don't want to check the order in which I call methods. This question points out that it's not thread-safe (not a concern in my case, plus I imagine it could be made thread-safe with some locks) and that setting the property to null will result in unintuitive behaviour (not a concern, because I don't have a setter at all and the backing field shouldn't be touched either way).
Also, if this kind of code IS bas practice, what is the proper way to ensure that my methods don't rely on order in which they are called?
As #madreflection said in the OP comments, use a method for anything that is possibly going to be slow. Getters and setters should just be quick ways of getting and setting a value.
Connections to dbs can be slow or fail to connect so you may have catches setup to try different connection methods etc.
You could also have the checking occur in the constructor of the object, that way the object cannot be used without init() being run in a different function, saving on time tracing where an error is actually occurring.
For example if you had one function create the object, do a bunch of 'stuff' then try to use the object without running init(), then you get the error after all of the 'stuff' not where you created the object. This could lead you to think there is something wrong in whatever way you are using the object, not that it has not been initialised.

How to accurately determine whether a method was called by an async method

I am trying to determine whether a particular method was called by an async method.
This answer (which was, granted, describing a somewhat different set of circumstances) suggested using CallerMemberName attribute to find the name of the calling method. Indeed, the signature of my method looks like this:
public void LogCallAsync([CallerMemberName] string caller = "", params object[] parameters)
which works great if you're doing something like
logger.LogCallAsync();
It would also work great if you have a fixed number of parameters. However, given that the next parameter is of type params object[], obviously that isn't the case, so if you try to do something like
logger.LogCallAsync(someObject, someOtherObject)
I'll get a compile exception because someObject isn't a string. I tried the following as a workaround:
logger.LogCallAsync(nameof(CurrentMethod), someObject, someOtherObject);
which is pretty ugly. Actually, I'd prefer it if I didn't have to do that, so if anyone has any suggestions in that regard that would be great, but on to my main question: is there some way of preventing people from calling this improperly? In particular, I'd like to know if "CurrentMethod" is, in fact, an actual async method.
If I look at an instance of StackTrace, for example, is there a reliable way of telling based on that? This article (if I'm reading it correctly) seems to imply that my current solution (see my code sample below) is correct, but it's not really an "authoritative" source and it's about 5 years old at this point.
Let me show a code sample to illustrate how I'm trying to solve this right now:
private static void GetCaller()
{
StackTrace stack = new StackTrace();
MethodBase method = stack.GetFrame(1).GetMethod();
Trace.TraceInformation("Method name: " + method.Name);
}
// Some arbitrary async method
private static async Task UseReflection()
{
// Do some kind of work
await Task.Delay(100);
// Figure out who called this method in the first place
// I want some way of figuring out that the UseReflection method is async
GetCaller();
}
static void Main(string[] args)
{
// AsyncPump is basically to make Async work more like it does on a UI application
// See this link: https://blogs.msdn.microsoft.com/pfxteam/2012/01/20/await-synchronizationcontext-and-console-apps/
AsyncPump.Run(async () =>
{
// In this case, it identifies the calling method as "MoveNext"
// Question: in cases like this, will this always be the case (i.e. will it always be MoveNext)?
await UseReflection();
});
// In this case, it identifies the calling method as "Main"
GetCaller();
}
I'm using Visual Studio 2015 and .NET 4.6 for what it's worth. My question, then, is: can I guarantee that code will always work in a way that's similar to what I have above? For example, if GetCaller was called by an async method, will I always get MoveNext off the stack trace? Also, does anyone know if Microsoft documents that somewhere (in case I'm asked to prove that my solution will work)?
EDIT: The primary purpose here is to log the name and parameters of the method that called the logger. If the caller is not async, then I know that the following code
StackTrace stack = new StackTrace();
MethodBase method = stack.GetFrame(1).GetMethod();
will give me information on who the caller is. However, that obviously won't work at all if the caller is async. In that case I currently do the following:
StackTrace st = new StackTrace();
StackFrame callFrame = st.GetFrames().ToList().FirstOrDefault(x => x.GetMethod().Name == caller);
where caller is the name of the method call that I passed, like in the signature I listed above:
public void LogCallAsync([CallerMemberName] string caller = "", params object[] parameters)
Obviously, this is less efficient. I could, in theory, just do this for every logger call, but it would be a little bit of a performance hit and I'd rather avoid that if possible.
Yes, all async methods end up in MoveNext.

How to create a Rhino Mock that has different behavior each time a method is called

I am trying to figure out how to create a mock using rhino mocks that will call the original method the first time a specific method (BasicPublish) is called, throw an exception the second time, then call the original method for all remaining calls to the method.
The original method signature looks like this:
public virtual void BasicPublish(
string exchange, string routingKey, IBasicProperties basicProperties, byte[] body)
Is this possible?
Here is what I have tried that I thought would work. My test is now calling the orginal method. But after setting a break point in my method and debugging my calls to BasicPublish, all the parameters are being passed through as null. Am I using the "CallOriginalMethod(OriginalCallOptions.CreateExpectation)" incorrectly?
mockModel.Stub(a => a.BasicPublish(Arg<string>.Is.Anything, Arg<string>.Is.Anything, Arg<IBasicProperties>.Is.Anything, Arg<byte[]>.Is.Anything)).CallOriginalMethod(OriginalCallOptions.NoExpectation).Repeat.Once();
mockModel.Stub(a => a.BasicPublish(Arg<string>.Is.Anything, Arg<string>.Is.Anything, Arg<IBasicProperties>.Is.Anything, Arg<byte[]>.Is.Anything)).Throw(new DivideByZeroException()).Repeat.Once();
mockModel.Stub(a => a.BasicPublish(Arg<string>.Is.Anything, Arg<string>.Is.Anything, Arg<IBasicProperties>.Is.Anything, Arg<byte[]>.Is.Anything)).CallOriginalMethod(OriginalCallOptions.NoExpectation).Repeat.Any();
Additional context: This is to be used in a unit test (using nunit) to test the behavior of a custom Log4Net Rabbit MQ appender. The test case is as follows: given a live connection to a queue, when the connection becomes faulty (simulated by an exception on a call to BasicPublish(...)), then that specific log message is ignored and following log messages are processed normally
I wasn't able to find a way to do this with Rhino but realized I could just create a fake myself that would behave the way I expected. This solution turned out to be very readable with proper naming conventions.

Verify that a method with particular parameters was not called using TypeMock

I am using Typemock for some of my unit tests. I have mocked static class Widget. I want to mock the return of Widget.GetPrice(123) to return value A.
Isolate.Fake.StaticMethods<Widget>();
Isolate.WhenCalled(() => Widget.GetPrice(123)).WillReturn("A");
I also want to verify that Widget.GetPrice(456) was NOT called.
Isolate.Verify.WasNotCalled(() => Widget.GetPrice(456));
It seems that WasNotCalled does not take parameters into consideration. The test comes back saying that it failed b/c Widget.GetPrice was in fact called.
The only way I could think to do this is to do a DoInstead call and increment a counter when Widget.GetPrice(456) is called. The end of the test would check if the counter was incremented. Is there a better way to do this though?
There are a couple of ways you can do this.
First, your DoInstead idea is pretty good, but I would tweak it to contain an assertion:
Isolate.WhenCalled(() => Widget.GetPrice(0)).DoInstead(
context =>
{
var num = (int)context.Parameters[0];
Assert.AreNotEqual(456, num);
return "A";
});
The idea there is that when the method is called, you verify at the time of the call that the incoming parameter is what you expect and fail the test with the Assert statement if it's not.
(You'll also note I put "0" in as the parameter because, as you noticed, the actual value doesn't matter. I find it's easier for future maintenance to use null/0/etc when the parameters don't matter so you don't "forget" or "get fooled" into thinking that it does matter.)
The second thing you could do is use WithExactArguments to control the behavior.
// Provide some default behavior that will break things
// if the wrong value comes in.
Isolate
.WhenCalled(() => Widget.GetPrice(0))
.WillThrow(new InvalidOperationException());
// Now specify the right behavior if the arguments match.
Isolate
.WhenCalled(() => Widget.GetPrice(123))
.WithExactArguments()
.WillReturn("A");
The "WithExactArguments" will make your behavior run only if the arguments match. When you run your test, if an invalid value gets passed in, the exception will get thrown and the test will fail.
Either way, you end up using the "WhenCalled" part of things to handle your assertion rather than a "Verify" call.
Disclaimer, I work in Typemock.
Since our API is constantly improving, check out another solution for your problem. You can use
Isolate.WhenCalled((<type arg1>, <type arg1>) => fake<method> (<arg1>, <arg2>)).AndArgumentsMatch((<arg1>, <arg2>) => <check>.<behavior>;
for setting your behavior for arguments you want.
Also, don't need to throw any exceptions. Use DoInstead() as shown below to verify, what method wasn't called with exact arguments. No inner assertion is needed.
[TestMethod, Isolated]
public void TestWidget()
{
Isolate.WhenCalled((int n) => Widget.GetPrice(n)).AndArgumentsMatch((n) => n == 123).WillReturn("A");
bool wasCalledWith456 = false;
Isolate.WhenCalled(() => Widget.GetPrice(456)).WithExactArguments().DoInstead((context) =>
{
wasCalledWith456 = true;
context.WillCallOriginal();
return null;
});
Assert.AreEqual("A", Widget.GetPrice(123));
Widget.GetPrice(234);
Widget.GetPrice(345);
Widget.GetPrice(456);
Assert.IsFalse(wasCalledWith456);
}

Unit testing void methods?

What is the best way to unit test a method that doesn't return anything? Specifically in c#.
What I am really trying to test is a method that takes a log file and parses it for specific strings. The strings are then inserted into a database. Nothing that hasn't been done before but being VERY new to TDD I am wondering if it is possible to test this or is it something that doesn't really get tested.
If a method doesn't return anything, it's either one of the following
imperative - You're either asking the object to do something to itself.. e.g change state (without expecting any confirmation.. its assumed that it will be done)
informational - just notifying someone that something happened (without expecting action or response) respectively.
Imperative methods - you can verify if the task was actually performed. Verify if state change actually took place. e.g.
void DeductFromBalance( dAmount )
can be tested by verifying if the balance post this message is indeed less than the initial value by dAmount
Informational methods - are rare as a member of the public interface of the object... hence not normally unit-tested. However if you must, You can verify if the handling to be done on a notification takes place. e.g.
void OnAccountDebit( dAmount ) // emails account holder with info
can be tested by verifying if the email is being sent
Post more details about your actual method and people will be able to answer better.
Update: Your method is doing 2 things. I'd actually split it into two methods that can now be independently tested.
string[] ExamineLogFileForX( string sFileName );
void InsertStringsIntoDatabase( string[] );
String[] can be easily verified by providing the first method with a dummy file and expected strings. The second one is slightly tricky.. you can either use a Mock (google or search stackoverflow on mocking frameworks) to mimic the DB or hit the actual DB and verify if the strings were inserted in the right location. Check this thread for some good books... I'd recomment Pragmatic Unit Testing if you're in a crunch.
In the code it would be used like
InsertStringsIntoDatabase( ExamineLogFileForX( "c:\OMG.log" ) );
Test its side-effects. This includes:
Does it throw any exceptions? (If it should, check that it does. If it shouldn't, try some corner cases which might if you're not careful - null arguments being the most obvious thing.)
Does it play nicely with its parameters? (If they're mutable, does it mutate them when it shouldn't and vice versa?)
Does it have the right effect on the state of the object/type you're calling it on?
Of course, there's a limit to how much you can test. You generally can't test with every possible input, for example. Test pragmatically - enough to give you confidence that your code is designed appropriately and implemented correctly, and enough to act as supplemental documentation for what a caller might expect.
As always: test what the method is supposed to do!
Should it change global state (uuh, code smell!) somewhere?
Should it call into an interface?
Should it throw an exception when called with the wrong parameters?
Should it throw no exception when called with the right parameters?
Should it ...?
Try this:
[TestMethod]
public void TestSomething()
{
try
{
YourMethodCall();
Assert.IsTrue(true);
}
catch {
Assert.IsTrue(false);
}
}
Void return types / Subroutines are old news. I haven't made a Void return type (Unless I was being extremely lazy) in like 8 years (From the time of this answer, so just a bit before this question was asked).
Instead of a method like:
public void SendEmailToCustomer()
Make a method that follows Microsoft's int.TryParse() paradigm:
public bool TrySendEmailToCustomer()
Maybe there isn't any information your method needs to return for usage in the long-run, but returning the state of the method after it performs its job is a huge use to the caller.
Also, bool isn't the only state type. There are a number of times when a previously-made Subroutine could actually return three or more different states (Good, Normal, Bad, etc). In those cases, you'd just use
public StateEnum TrySendEmailToCustomer()
However, while the Try-Paradigm somewhat answers this question on how to test a void return, there are other considerations too. For example, during/after a "TDD" cycle, you would be "Refactoring" and notice you are doing two things with your method... thus breaking the "Single Responsibility Principle." So that should be taken care of first. Second, you might have idenetified a dependency... you're touching "Persistent" Data.
If you are doing the data access stuff in the method-in-question, you need to refactor into an n-tier'd or n-layer'd architecture. But we can assume that when you say "The strings are then inserted into a database", you actually mean you're calling a business logic layer or something. Ya, we'll assume that.
When your object is instantiated, you now understand that your object has dependencies. This is when you need to decide if you are going to do Dependency Injection on the Object, or on the Method. That means your Constructor or the method-in-question needs a new Parameter:
public <Constructor/MethodName> (IBusinessDataEtc otherLayerOrTierObject, string[] stuffToInsert)
Now that you can accept an interface of your business/data tier object, you can mock it out during Unit Tests and have no dependencies or fear of "Accidental" integration testing.
So in your live code, you pass in a REAL IBusinessDataEtc object. But in your Unit Testing, you pass in a MOCK IBusinessDataEtc object. In that Mock, you can include Non-Interface Properties like int XMethodWasCalledCount or something whose state(s) are updated when the interface methods are called.
So your Unit Test will go through your Method(s)-In-Question, perform whatever logic they have, and call one or two, or a selected set of methods in your IBusinessDataEtc object. When you do your Assertions at the end of your Unit Test you have a couple of things to test now.
The State of the "Subroutine" which is now a Try-Paradigm method.
The State of your Mock IBusinessDataEtc object.
For more information on Dependency Injection ideas on the Construction-level... as they pertain to Unit Testing... look into Builder design patterns. It adds one more interface and class for each current interface/class you have, but they are very tiny and provide HUGE functionality increases for better Unit-Testing.
You can even try it this way:
[TestMethod]
public void ReadFiles()
{
try
{
Read();
return; // indicates success
}
catch (Exception ex)
{
Assert.Fail(ex.Message);
}
}
it will have some effect on an object.... query for the result of the effect. If it has no visible effect its not worth unit testing!
Presumably the method does something, and doesn't simply return?
Assuming this is the case, then:
If it modifies the state of it's owner object, then you should test that the state changed correctly.
If it takes in some object as a parameter and modifies that object, then your should test the object is correctly modified.
If it throws exceptions is certain cases, test that those exceptions are correctly thrown.
If its behaviour varies based on the state of its own object, or some other object, preset the state and test the method has the correct Ithrough one of the three test methods above).
If youy let us know what the method does, I could be more specific.
Use Rhino Mocks to set what calls, actions and exceptions might be expected. Assuming you can mock or stub out parts of your method. Hard to know without knowing some specifics here about the method, or even context.
Depends on what it's doing. If it has parameters, pass in mocks that you could ask later on if they have been called with the right set of parameters.
What ever instance you are using to call the void method , You can just use ,Verfiy
For Example:
In My case its _Log is the instance and LogMessage is the method to be tested:
try
{
this._log.Verify(x => x.LogMessage(Logger.WillisLogLevel.Info, Logger.WillisLogger.Usage, "Created the Student with name as"), "Failure");
}
Catch
{
Assert.IsFalse(ex is Moq.MockException);
}
Is the Verify throws an exception due to failure of the method the test would Fail ?

Categories