UnitTests: how to test dependent methods where mocking is unfeasible? - c#

I'm fairly new to UnitTesting and just encountered a situation I don't know how to handle and I'd appreciate any hints :)
The situation is as follows, imagine two methods:
// simple standalone method
public bool HelperMethod(string substr) {
return substr.Equals("abc");
}
// complex method making (multiple) use of HelperMethod
public bool ActualMethod(string str) {
for (var i=0; i<str.Length; i++) {
var substr = str.Substring(i, 3);
if (HelperMethod(substr))
return true;
}
return false;
}
HelperMethod functions without dependencies, ActualMethod however depends on HelperMethod and therefore its UnitTest will fail if HelperMethod's one does.
Actually, if I'm not mistaken, this is where mocking/dependency injection should come to rescue.
But in this specific case, I'd like to test several (arbitrary large) edge-cases (which may not be necessary for the code above, but the actual ActualMethod implementation is a part of fairly complex syntax parser). Since HelperMethod is called multiple times in each ActualMethod call, I would have to mock hundreds of HelperMethod calls for my test which just seems unbearable (now just imagine the number of needed HelperMethod calls would be quadratic to the input..).
My question is: how could one elegantly test a method that delegates a huge number of calls to another method? Should I really mock all these delegate calls? Or am I maybe allowed to make the method test depend on the other method's test (sth. like Assert(HelperMethodPassed)? Or is there no way around changing the design of the implementation?
Unfortunately inlining HelperMethod in the ActualMethod isn't possible because other methods rely on it as well.
Thanks in advance, I'd really appreciate any help! :)
PS:
The project that is being tested is written in C# and I'm currently using the MSTest framework (but I'm open for switching to another framework if this solves the problematic).
Edit: explicitly marked HelperMethod and ActualMethod as public.

In general, if code is difficult to isolate for testing, it points to a design problem.
Since you're calling HelperMethod a bunch of times in the context of the method you're trying to test, it sounds like the problem is that ActualMethod is doing too much. You can make it more unit testable by breaking ActualMethod down into smaller methods that take the output of HelperMethod as a parameter, and then unit testing each of those individual methods.
Of course, you'll want to ensure that HelperMethod is unit tested as well!
As other folks have stated, if the HelperMethod is private and not used outside the class, then you can ignore the above advice and ensure that HelperMethod is tested by making sure that you cover every reasonable permutation of test cases via the public interface (e.g. ActualMethod). Fundamentally, though, if HelperMethod contains complex logic, it should probably be unit tested independently.

If MethodHelper is an implementation detail and is consequently a private method in the same class as ActualMethod then I don't see a reason to test it seperately from ActualMethod. You should be able to achieve full coverage by testing ActualMethod.

What you can do is:
Test HelperMethod so that all possible invocations from ActualMethod are covered in the unit tests.
Then assume that HelperMethod works and do not mock it, but use the actual implementation if you can guarantee that there aren't any side effects.
If the tests for HelperMethod fail, you can consider anything that ActualMethod does as undefined behavior, so it is not relevant if these tests pass or fail.

Related

How can I test if a private method of a class is called or not with rhino mock?

I am quite new at C# and also rhino mocks. I searched and found similar topics with my question but couldnt find a proper solution.
I am trying to understand if the private method is called or not in my unit test. I am using rhino mock, read many files about it, some of them just say that change the access specifier of the method from private to public, but I can not change the source code. I tried to link source file to my test project but it doesnt change.
public void calculateItems()
{
var result = new Result(fileName, ip, localPath, remotePath);
calculateItems(result, nameOfString);
}
private void calculateItems(Result result, string nameOfString )
As you see from the code above, I have two methods have exactly same name, calculateItems, but public one has no parameter, private one has two parameters. I am trying to understand when I called public one in my unittest, is private method called?
private CalculateClass sut;
private Result result;
[SetUp]
public void Setup()
{
result = MockRepository.GenerateStub<Result>();
sut = new CalculateClass();
}
[TearDown]
public void TearDown()
{
}
[Test]
public void test()
{
sut.Stub(stub => stub.calculateItems(Arg<Result>.Is.Anything, Arg<string>.Is.Anything));
sut.calculateItems();
sut.AssertWasCalled(stub => stub.calculateItems(Arg<Result>.Is.Anything, Arg<string>.Is.Anything));
}
In my unittest, I am taking such an error which says "No overload method for calculateItems take two arguments". Is there a way to test it without any changing in source code?
You're testing the wrong thing. Private methods are private. They are of no concern to consuming code, and unit tests are consuming code like any other.
In your tests you test and validate the outward facing functionality of the component. Its inner implementation details aren't relevant to the tests. All the tests care about is whether the invoked operation produces the expected results.
So the question you must ask yourself is... What are the expected results when invoking this operation?:
calculateItems()
It doesn't return anything, so what does it do? What state does it modify in some way? That is what your test needs to observe, not the implementation details but the observable result. (And if the operation has no observable result, then there's no difference between "passed" or "failed" so there's nothing to test.)
We can't see the details of your code, but it's possible that the observable result is coupled to another component entirely. If that's the case then that other component is a dependency for this operation and the goal of the unit test is to mock that dependency so the operation can be tested independently of the dependency. The component may then need to be modified so that a dependency is provided rather than internally controlled. (This is referred to as the Dependency Inversion Principle.)
Also of note...
but I can not change the source code
That's a separate problem entirely. If you truly can't change the source code, then the value of these tests is drastically reduced and possibly eliminated entirely. If a test fails, what can you do about it? Nothing. Because you can't change the code. So what are you testing?
Keep in mind that it's not only possible but unfortunately very common for programmers to write code which can't be meaningfully unit tested. If this code was provided to you by someone else and you are forbidden to change it for some non-technical reason, then it will be the responsibility of that someone else to correct the code. "Correcting" may include "making it possible to meaningfully unit test". (Or, honestly, they should be unit testing it. Not you.)
If your public method calls your private one then the same thing will happen in your tests. Tests are nothing more than code that can be run and debugged and you can try that so see what happens.
Private methods can't be tested directly but they can be tested via their public callers which is what you are doing, so it's all good. Whether it's a good idea to have a setup like this well, that's a different story entirely but I am not going into that now.
Now, let's discuss what you are actually testing.
Unit tests should not have deep knowledge of the code they test. The reason is that you should have inputs and outputs and you shouldn't care what happens in between.
If you refactor the code and eliminate the private method then your test would break, even if your inputs and outputs to your public method remain the same. That's not a good position to be in, this is what we call brittle tests.
So add your functional tests around the public method, verify that you get hat you expect and don't worry whether it calls your private method or not.
When you say you need to know whether your private methods are called, this can have two different interpretations:
You want to ensure that the private method is called within one particular test, making it a success criterion for that very test.
You want to know if the private method is called at all, by any of your test cases. You might be interested in this because you want to be sure if the private method is covered by your test suite, or as you said, just to form an understanding of what is actually going on in your code.
Regarding the second interpretation: If you want to understand what is going on in the code, a good approach is to use a debugger and just step through the code to see what function is called. As I am not a C# expert here, I can not recommend any specific debugging tool, but finding some recommendations about this on the web should not be difficult. This approach would fulfill your requirements not to require changes to the source code
Another possibility, in particular if you are interested in whether your private function is covered by the tests, is to use a test coverage tool for C#. The coverage tool would show you whether or not the private method was called or not. Again, this would not require to make any changes to the source code.
Regarding the first interpretation of your question: If you want to test that some privat function is called as part of your test's success criterion, you preferrably do this with tests that use the public API. Then, in these tests, you should be able to judge if the private function is called because of the effect that the private function has on the test result.
And, in contrast to other opinions, you should test the implementation. The primary goal of unit-testing is to find the bugs in the code. Different implementations have different bugs. This is why people also use coverage tools, to see if they have covered the code of their implementation. And, coverage is not enough, you also need to check boundary cases of expressions etc. Certainly, having maintainable tests and tests that do not break unnecessarily in case of refactorings are good goals (why testing through the public API is typically a good approach - but not always), but they are secondary goals compared to the goal to find all bugs.

Rhino Mocks: How to Mock a Database call in a Parameterless Method?

I am writing unit tests for an ASP.NET MVC application in C# using NUnit and Rhino Mocks. I am having some trouble testing this method:
public void Install()
{
Database.SetInitializer<DraftOrderObjectContext>(null);
var dbScript = CreateDatabaseInstallationScript();
Database.ExecuteSqlCommand(dbScript);
SaveChanges();
}
Just to clarify, Database is not referring to a local object. The first one "Database.SetInitializer..." refers to:
System.Data.Entity.Database
and the second "Database.ExecuteSqlCommand..." refers to:
System.Data.Entity.DbContext.Database
Since the method does not return anything, I figured it would be sufficient to make a mock and verify that Database.ExecuteSqlCommand(dbScript); was called at least once.
Now I've done this before, but that involved passing a database context to the method, which is easy enough to mock, however, in this case there are no parameters. I need to somehow find a way to mock 'Database'.
I have tried straight up assigning a mock like so:
System.Data.Entity.DbContext.Database = MockRepository.GenerateMock<System.Data.Entity.DbContext.Database>();
but that breaks syntax because the property is read only.
I have also tried mocking DbContext like so:
System.Data.Entity.DbContext instance = MockRepository.GenerateMock<System.Data.Entity.DbContext>();
instance.Expect(someCaller => someCaller.Database.ExecuteSqlCommand("sql"))
.IgnoreArguments()
.Return(1)
.Repeat.Times(1);
but I get a runtime error saying DbContext.getHashCode() must return a value. I then tried stubbing the getHashCode method to make it return something but that had no effect.
I am still fairly new to mocking so I may be missing some fundamental concept here. My apologies if that is the case. Any help is much appreciated!
I'm afraid the only answer worth giving here is that the code must be modified to be more test-friendly. Trying to write unit tests for methods that make calls to static classes, properties or methods is not a rewarding or worthwhile task. You suggest that you may be missing a fundamental concept here and this may be it: static is unit testing's worst enemy and the collective wisdom is that there isn't much point putting a lot of effort into testing things that use static resources. Just refactor the code.
If refactoring the code is truly impossible then why would you need to unit test it (this is not a rhetorical question, please comment)? If the concern is that you need to mock these objects as part of other tests, then you should wrap the evil, unmodifiable code with a test friendly interface and mock that instead.

How to keep my unit tests DRY when mocking doesn't work?

Edit:
It seems that by trying to provide some solutions to my own problem I blurred the whole problem. So I'm modifying the question little bit.
Suppose I have this class:
public class ProtocolMessage : IMessage
{
public IHeader GetProtocolHeader(string name)
{
// Do some logic here including returning null
// and throw exception in some cases
return header;
}
public string GetProtocolHeaderValue(string name)
{
IHeader header = GetProtocolHeader(name);
// Do some logic here including returning null
// and throw exception in some cases
return value;
}
}
It is actually not important what's going on in these methods. The important is that I have multiple unit tests to cover GetProtocolHeader method covering all situations (returning correct header, null or exception) and now I'm writing unit tests for GetProtocolHeaderValue.
If GetProtocolHeaderValue would be dependent on external dependency I would be able to mock it and inject it (I'm using Moq + NUnit). Then my unit test would just test expectation that external dependency was called and returned expected value. The external dependency would be tested by its own unit test and I would be done but how to correctly proceed in this example where method is not external dependency?
Clarification of the problem:
I believe my test suite for GetProtocolHeaderValue must test situation where GetProtocolHeader returns header, null or exception. So the main question is: Should I write tests where GetProtocolHeader will be really executed (some tests will be duplicated because they will test same code as tests for GetProtocolHeader itself) or should I use mocking approach described by #adrift and #Eric Nicholson where I will not run real GetProtoclHeader but just configure mock to return header, null or exception when this method is called?
In the call to GetProtocolHeaderValue, do you actually need to know whether or not it called GetProtocolHeader?
Surely it is enough to know that it is getting the correct value from the correct header. How it actually got it is irrelevant to the unit test.
You are testing units of functionality, the unit of functionality of GetProtocolHeaderValue is whether it returns the expected value, given a header name.
It is true that you may wish to guard against inappropriate caching or cross-contamination or fetching the value from a different header, but I don't think that testing that it has called GetProtocolHeader is the best way to do this. You can infer that it somehow fetched the right header from the fact that it returned the expected value for the header.
As long as you craft your tests and test data in such a way as to ensure that duplicate headers don't mask errors, then all should be well.
EDIT for updated question:
If GetProtocolHeader works quickly, reliably and is idempotent, then I still believe that there is no need to mock it. A shortfall in any of those three aspects is (IMO) the principal reason for mocking.
If (as I suspect from the question title), the reason you wish to mock it is that the preamble required to set up an appropriate state to return a real value is too verbose, and you'd rather not repeat it across the two tests, why not do it in the setup phase?
One of the roles performed by good unit tests is documentation.
If someone wishes to know how to use your class, they can examine the tests, and possibly copy and alter the test code to fit their purpose. This becomes difficult if the real idiom of usage has been obscured by the creation and injection of mocks.
Mocks can obscure potential bugs.
Let's say that GetProtocolHeader throws an exception if name is empty. You create a mock accordingly, and ensure that GetProtocolHeaderValue handles that exception appropriately. Later, you decide that GetProtocolHeader should return null for an empty name. If you forget to update your mock, GetProtocolHeaderValue("") will now behave differently in real life vs. the test suite.
Mocking might present an advantage if the mock is less verbose than the setup, but give the above points due consideration first.
Though you give three different GetProtocolHeader responses (header, null or exception) that GetProtocolHeaderValue needs to test, I imagine that the first one is likely to be "a range of headers". (e.g. What does it do with a header that is present, but empty? How does it treat leading and trailing whitespace? What about non-ASCII chars? Numbers?). If the setup for all of these is exceptionally verbose, it might be better to mock.
I often use a partial mock (in Rhino) or the equivalent (like CallsBaseMethod in FakeItEasy) to mock the actual class I'm testing. Then you can make GetProtocolHeader virtual and mock your calls to it. You could argue that it's violating the single responsibility principal, but that's still clearly very cohesive code.
Alternatively you could make a method like
internal static string GetProtocolHeaderValue(string name, IHeader header )
and test that processing independently. The public GetProtocolHeaderValue method wouldn't have any/many tests.
Edit: In this particular case, I'd also consider adding GetValue() as an extension method to IHeader. That would be very easy to read, and you could still do the null checking.
I'm probably missing something, but given the code listed it seems to me that you don't need to worry about whether its called or not.
Two possibilities exist:
That the GetProtocolHeader() method needs to be public in which case you write the set of tests that tell you whether it works as expected or not.
That its an implementation detail and doesn't need to be public except in so far as you want to be able to test it directly but in that case all you really care about is the set of tests that tell you whether GetProtocolHeaderValue() works as required.
In either case you are testing the exposed functionality and at the end of the day that's all that matters. If it were a dependency then yes you might be worrying about whether it was called but if its not the surely its an implemenation detail and not relevant?
With Moq, you can use CallBase to do the equivalent of a partial mock in Rhino Mocks.
In your example, change GetProtocolHeader to virtual, then create a mock of ProtocolMessage, setting CallBase = true. You can then setup the GetProtocolHeader method as you wish, and have your base class functionality of GetProtocolHeaderValue called.
See the Customizing Mock Behavior section of the moq quickstart for more details.
Why not simply change GetProtocolHeaderValue(string name) so that it calls 2 methods, the second one accepting a IHeader? That way, you can test all the // do some logic part in a separate test, via the RetrieveHeaderValue method, without having to worry about Mocks. Something like:
public string GetProtocolHeaderValue(string name)
{
IHeader header = GetProtocolHeader(name);
return RetrieveHeaderValue(IHeader header);
}
now you can test both parts of GetProtocolHeaderValue fairly easily. Now you still have the same problem testing that method, but the amount of logic in it has been reduced to a minimum.
Following the same line of thinking, these methods could be extracted in a IHeaderParser interface, and the GetProtocol methods would take in a IHeaderParser, which would be trivial to test/mock.
public string GetProtocolHeaderValue(string name, IHeaderParser parser)
{
IHeader header = parser.GetProtocolHeader(name);
return parser.HeaderValue(IHeader header);
}
Try the simplest thing that might work.
If the real GetProtocolHeader() implementation is quick and easy to control (e.g. to simulate header, null and exception cases), just use it.
If not (i.e. either the real implementation is time-consuming or you can easily simulate the 3 cases), then look at redesigning such that the constraints are eased.
I refrain from using Mocks unless absolutely required (e.g. file/network/external dependency), but as you may know this is just a personal choice not a rule. Ensure that the choice is worth the extra cognitive overhead (drop in readability) of the test.
It's all a matter of oppinion, pure tdd-ists will say no mocks, mockers will mock it all.
In my honest oppinion there is something wrong with the code you wrote, the GetProtocolHeader seems important enough not to be discarded as an implementation detail, as you defined it public.
The problem here lies within the second method GetProtocolHeaderValue that does not have the possibility to use an existing instance of IHeader
I would suggest a GetValue(string name) on IHeader interface

Patterns or practices for unit testing methods that call a static method

As of late, I have been pondering heavily about the best way to "Mock" a static method that is called from a class that I am trying to test. Take the following code for example:
using (FileStream fStream = File.Create(#"C:\test.txt"))
{
string text = MyUtilities.GetFormattedText("hello world");
MyUtilities.WriteTextToFile(text, fStream);
}
I understand that this is a rather bad example, but it has three static method calls that are all different slightly. The File.Create function access the file system and I don't own that function. The MyUtilities.GetFormattedText is a function that I own and it is purely stateless. Finally, the MyUtilities.WriteTextToFile is a function I own and it accesses the file system.
What I have been pondering lately is if this were legacy code, how could I refactor it to make it more unit-testable. I have heard several arguments that static functions should not be used because they are hard to test. I disagree with this idea because static functions are useful and I don't think that a useful tool should be discarded just because the test framework that is being used can't handle it very well.
After much searching and deliberation, I have come to the conclusion that there are basically 4 patterns or practices that can be used in order to make functions that call static functions unit-testable. These include the following:
Don't mock the static function at all and just let the unit test call it.
Wrap the static method in an instance class that implements an interface with the function that you need on it and then use dependency injection to use it in your class. I'll refer to this as interface dependency injection.
Use Moles (or TypeMock) to hijack the function call.
Use dependeny injection for the function. I'll refer to this as function dependency injection.
I've heard quite a lot of discussion about the first three practices, but as I was thinking about solutions to this problem, the forth idea came to me of function dependency injection. This is similar to hiding a static function behind an interface, but without actually needing to create an interface and wrapper class. An example of this would be the following:
public class MyInstanceClass
{
private Action<string, FileStream> writeFunction = delegate { };
public MyInstanceClass(Action<string, FileStream> functionDependency)
{
writeFunction = functionDependency;
}
public void DoSomething2()
{
using (FileStream fStream = File.Create(#"C:\test.txt"))
{
string text = MyUtilities.GetFormattedText("hello world");
writeFunction(text, fStream);
}
}
}
Sometimes, creating an interface and wrapper class for a static function call can be cumbersome and it can pollute your solution with a lot of small classes whose sole purpose is to call a static function. I am all for writing code that is easily testable, but this practice seems to be a workaround for a bad testing framework.
As I was thinking about these different solutions, I came to an understanding that all of the 4 practices mentioned above can be applied in different situations. Here is what I am thinking is the correct cicumstances to apply the above practices:
Don't mock the static function if it is purely stateless and does not access system resources (such as the filesystem or a database). Of course, the argument can be made that if system resources are being accessed then this introduces state into the static function anyway.
Use interface dependency injection when there are several static functions that you are using that can all logically be added to a single interface. The key here is that there are several static functions being used. I think that in most cases this will not be the case. There will probably only be one or two static functions being called in a function.
Use Moles when you are mocking up external libraries such as UI libraries or database libraries (such as linq to sql). My opinion is that if Moles (or TypeMock) is used to hijack the CLR in order to mock your own code, then this is an indicator that some refactoring needs to be done to decouple the objects.
Use function dependency injection when there is a small number of static function calls in the code that is being tested. This is the pattern that I am leaning towards in most cases in order to test functions that are calling static functions in my own utility classes.
These are my thoughts, but I would really appreciate some feedback on this. What is the best way to test code where an external static function is being called?
Using dependency injection (either option 2 or 4) is definitely my preferred method of attacking this. Not only does it make testing easier it helps to separate concerns and keep classes from getting bloated.
A clarification I need to make though is it is not true that static methods are hard to test. The problem with static methods occurs when they are used in another method. This makes the method that is calling the static method hard to test as the static method can not be mocked. The usual example of this is with I/O. In your example you are writing text to a file (WriteTextToFile). What if something should fail during this method? Since the method is static and it can't be mocked then you can't on demand create cases such as failure cases. If you create an interface then you can mock the call to WriteTextToFile and have it mock errors. Yes you'll have a few more interfaces and classes but normally you can group similar functions together logically in one class.
Without Dependency Injection:
This is pretty much option 1 where nothing is mocked. I don't see this as a solid strategy because it does not allow you to thoroughly test.
public void WriteMyFile(){
try{
using (FileStream fStream = File.Create(#"C:\test.txt")){
string text = MyUtilities.GetFormattedText("hello world");
MyUtilities.WriteTextToFile(text, fStream);
}
}
catch(Exception e){
//How do you test the code in here?
}
}
With Dependency Injection:
public void WriteMyFile(IFileRepository aRepository){
try{
using (FileStream fStream = aRepository.Create(#"C:\test.txt")){
string text = MyUtilities.GetFormattedText("hello world");
aRepository.WriteTextToFile(text, fStream);
}
}
catch(Exception e){
//You can now mock Create or WriteTextToFile and have it throw an exception to test this code.
}
}
On the flip side of this is do you want your business logic tests to fail if the file system/database can't be read/written to? If we're testing that the math is correct in our salary calculation we don't want IO errors to cause the test to fail.
Without Dependency Injection:
This is a bit of a strange example/method but I am only using it to illustrate my point.
public int GetNewSalary(int aRaiseAmount){
//Do you really want the test of this method to fail because the database couldn't be queried?
int oldSalary = DBUtilities.GetSalary();
return oldSalary + aRaiseAmount;
}
With Dependency Injection:
public int GetNewSalary(IDBRepository aRepository,int aRaiseAmount){
//This call can now be mocked to always return something.
int oldSalary = aRepository.GetSalary();
return oldSalary + aRaiseAmount;
}
Increased speed is an additional perk of mocking. IO is costly and reduction in IO will increase the speed of your tests. Not having to wait for a database transaction or file system function will improve your tests performance.
I've never used TypeMock so I can't speak much about it. My impression though is the same as yours that if you have to use it then there is probably some refactoring that could be done.
Welcome to the evils of static state.
I think your guidelines are OK, on the whole. Here are my thoughts:
Unit-testing any "pure function", which does not produce side effects, is fine regardless of the visibility and scope of the function. So, unit-testing static extension methods like "Linq helpers" and inline string formatting (like wrappers for String.IsNullOrEmpty or String.Format) and other stateless utility functions is all good.
Singletons are the enemy of good unit-testing. Instead of implementing the singleton pattern directly, consider registering the classes you want restricted to a single instance with an IoC container and injecting them to dependent classes. Same benefits, with the added benefit that IoC can be set up to return a mock in your testing projects.
If you simply must implement a true singleton, consider making the default constructor protected instead of fully private, and define a "test proxy" that derives from your singleton instance and allows for the creation of the object in instance scope. This allows for the generation of a "partial mock" for any methods that incur side effects.
If your code references built-in statics (such as ConfigurationManager) which are not fundamental to the operation of the class, either extract the static calls into a separate dependency which you can mock, or look for an instance-based solution. Obviously, any built-in statics are un-unit-testable, but there's no harm in using your unit-testing framework (MS, NUnit, etc) to build integration tests, just keep them separate so you can run unit tests without needing a custom environment.
Wherever code references statics (or has other side effects) and it is infeasible to refactor into a completely separate class, extract the static call into a method, and test all other class functionality using a "partial mock" of that class that overrides the method.
Just create a unit test for static method and feel free to call it inside methods to test without mock it.
For the File.Create and MyUtilities.WriteTextToFile, I'd create my own wrapper and inject it with dependency injection. Since it touchs the FileSystem, this test could slow down because of the I/O and maybe even throw up some unexpected exception from the FileSystem which would lead you to think that your class is wrong, but it's now.
As for the MyUtilities.GetFormattedText function, I suppose this function only does some changes with the string, nothing to worry about here.
Choice #1 is the best. Don't mock, and just use the static method as it exists. This is the simplest route and does exactly what you need it to do. Both of your 'injection' scenarios are still calling the static method, so you aren't gaining anything through all of the extra wrapping.

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