Can I mock SqlConnection.BeginTransaction c#? - c#
I have to work with some legacy code that I cannot change. I have to write classes of that implement an interface called "ITask" that has a method called "RunTask" that accepts a concrete type called Schedule e.g;
public void RunTask(Schedule thisSchedule)
{
//I have to do stuff with thisSchedule, no I can't fix that name...
}
Although the legacy code does not use unit testing I would dearly like to use it for my work but the problem is "thisSchedule". I have made a fake version of Schedule that derives from it and am attempting to take control over how all the methods within it function (it is probably a fool's errand). So far I have been successful by exploiting the alarming number of virtual methods or by using reflection but I have hit my first show-stopper
I cannot connect to the real database and I have a method that is often called;
public void BeginTransaction()
{
MyTransaction = MyConnection.BeginTransaction(IsolationLevel.RepeatableRead);
}
internal SqlConnection MyConnection = new System.Data.SqlClient.SqlConnection();
This throws an exception because the connection is closed, Ideally I would like to be able to set a flag stating that the method was called and then just swallow the exception but I would be happy to simply ignore the exception.
Anything, no matter how nasty that will allow me to get past this method call would be an acceptable answer. It's that or defeat.
I am not allowed to use paid-for services like typeMock or shims in visual studio enterprise.
EDIT
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Data;
using System.Data.SqlClient;
namespace PredictionServicesTests
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void BeginTransaction_WhenCalled_SetsTransactionStartedToTrue()
{
Schedule schedule = new FakeSchedule();
schedule.BeginTransaction(); //It would be enough to simply get past this line to the Assert
Assert.IsTrue(((FakeSchedule)schedule).TransactionStarted); //This would be nice, but isn't vital
}
class Schedule
{
private SqlTransaction MyTransaction;
internal SqlConnection MyConnection = new System.Data.SqlClient.SqlConnection();
public void BeginTransaction()
{
MyTransaction = MyConnection.BeginTransaction(IsolationLevel.RepeatableRead);
}
}
class FakeSchedule : Schedule
{
public bool TransactionStarted { get; set; }
}
}
}
Please remember I cannot change the Schedule class, if only things could be that simple!
The ITask interface;
interface ITask
{
void RunTask(Schedule thisSchedule);
}
When it comes to unit testing, any external dependency needs to be isolated. Different frameworks have different ways of isolating external dependencies, as well as limitations of what they can isolate.
Many frameworks allow you to create a mock of an interface, so that you can provide an implementation for members in a controlled state. A lot of these frameworks also work well with abstract members of abstract classes. However, very few frameworks support the ability to provide an implementation on a concrete class (non-abstract member). The only two I'm aware which are available are:
Typemock Isolator
Microsoft Fakes
Both of these frameworks utilize the .NET Profiler API to intercept member calls to replace them with code you provide. I'm not too familiar with TypeMock Isolator, but I am very familiar with Microsoft Fakes. The Microsoft Fakes framework supports generating an assembly (i.e. System.Fakes.dll) which contains classes that allow you to provide your own implementation on members. It supports creating Stubs against interfaces and abstract classes (equivalent to "mocks"), and Shims against concrete and static classes.
If you choose to use Microsoft Fakes, you'll first need to generate a fake assembly against System.Data.dll, which is where SqlConnection resides. This will generate the ShimSqlConnection class, and this class will contain members which allow you to provide alternative implementations of the SqlConnection class' members. Here is an example of how that could be done:
[TestMethod]
public void SampleTest()
{
using (ShimsContext.Create())
{
// Arrange
SqlConnection.AllInstances.BeginTransactionIsolationLevel =
(instance, iso) => { ... };
// Act
// Assert
}
}
Of course, whether it is a mock, shim, stub, whatever... you should provide alternative implementation which simulates the behavior you want. Since you are replacing the SqlConnection.BeginTransaction(IsolationLevel) member, you must still follow it's contract and expected behavior; you should not return a value or throw an exception that the actual implementation would not do. At my company, we utilize Microsoft Fakes to simulate scenarios such as:
What happens if a Stream is closed when we read from it?
What happens if the user/pass is wrong for an HttpWebRequest?
What happens if we want our database to return two rows (i.e. control the SqlDataReader.Read() member)?
In all of these scenarios, our goal was to isolate the implemented behavior of these members and replace them with implementations which could realistically occur in a controlled experiment.
Update:
I just noticed that the original poster stated "I am not allowed to use paid-for services like typeMock or shims in visual studio enterprise.". If that is a restriction, then you will have to find another tool that I am unaware of that utilizes the .NET Profiler API or utilize the framework yourself. Profiling (Unmanaged API Reference).
The fact that you are "newing" up the SQL connection within the class makes it difficult to invert the control and make it more unit test friendly.
Another option would be to connect to a dummy database and use that connection. The dummy database would have just enough to allow the test to be exercised as an integration test.
That legacy code should be treated as 3rd party code you have no control over. And you should not waste time testing 3rd part code you have no control over. Common practice is to encapsulate 3rd party code behind an abstraction you do control and use that. The legacy code demonstrates technical debt that is being cashed in with the current difficulties that it is presenting because of poor design.
Not much else can be done given the current restrictions.
The closest I could get was to create an interface named IFake that I would apply to FakeSchedule;
public interface IFake
{
Action GetFakeAction(Action action);
}
public class FakeSchedule : Schedule, IFake
{
public bool TransactionStarted { get; set; }
public Action GetFakeAction(Action action)
{
return () => TransactionStarted = true;
}
}
I then created the following extension method;
public static void Testable<T>(this T obj, Action action)
{
if(obj is IFake)
{
action = ((IFake)obj).GetFakeAction(action);
}
action();
}
This allowed me to call the BeginTransaction method like this;
[TestMethod]
public void BeginTransaction_WhenCalled_SetsTransactionStartedToTrue()
{
Schedule schedule = new FakeSchedule();
var connection = new SqlConnection();
schedule.Testable(schedule.BeginTransaction);
Assert.IsTrue(((FakeSchedule)schedule).TransactionStarted);
}
Obviously this solution is far from ideal but it works, if I'm running a unit test then the call to begin transaction is diverted away from the real implementation.
The version I implement will need some work (my implementation of GetFakeAction is too dumb) but it's the closest I think I am going to get, the only other solution I can see would be to either use Prig or to follow NKosi's answer and connect to a dummy database.
Related
What should you do about nested ViewModels when you are unit testing?
I was working on creating some unit tests for my ViewModels in my project. I didn't really have a problem as most of them were very simple, but ran into an issue when I had a new (unfinished) ViewModel inside of my other ViewModel. public class OrderViewModel : ViewModelBase { public OrderViewModel(IDataService dataService, int orderId) { \\ ... Payments = new ObservableCollection<PaymentViewModel>(); } public ObservableCollection<PaymentViewModel> Payments { get; private set; } public OrderStatus Status { ... } //INPC public void AddPayment() { var vm = new PaymentViewModel(); payments.Add(vm); // TODO: Subscribe to PaymentViewModel.OnPropertyChanged so that // if the payment is valid, we update the Status to ready. } } I want to create a unit test so that if any of my PaymentViewModel's IsValid property changes and all of them are true that Status should be OrderStatus.Ready. I can implement the class, but what gets me worried is that my unit test will break if the problem is in PaymentViewModel. I'm not sure if this is OK or not, but it just feels like I should not have to worry about whether or not PaymentViewModel operates properly in order for my unit test for OrderViewModel is correct. public void GivenPaymentIsValidChangesAndAllPaymentsAreValid_ThenStatusIsReady() { var vm = new OrderViewModel(); vm.AddPayment(); vm.AddPayment(); foreach (var payment in vm.Payments) { Assert.AreNotEqual(vm.Status, OrderStatus.Ready); MakePaymentValid(payment); } // Now all payments should be valid, so the order status should be ready. Assert.AreEqual(vm.Status, OrderStatus.Ready); } The problem is, how do I write MakePaymentValid in such a way that I guarantee that the PaymentViewModel's behavior will not negatively impact my unit test? Because if it does, then my unit test will fail based on another piece of code not working, rather than my code. Or, should it fail if PaymentViewModel is wrong as well? I am just torn in that I don't think that my tests for OrderViewModel should fail if PaymentViewModel has a bug. I realize that I could always create an interface like how I do with IDataService, but it seems to me that that is a bit of an overkill to have every single ViewModel have an interface and injected in some how?
When it comes to unit testing you absolutely should separate out your tests from any external dependencies. Keep in mind that this does not mean you must pass in some interface; you will run into situations where you have a specific class being utilized, whether that class is in or out of your control. Imagine that instead of your example, you were relying on DateTime.Now. Some would argue to abstract it away into some sort of interface IDateTimeService, which could work. Alternatively, you could take advantage of Microsoft Fakes: Shims & Stubs. Microsoft Fakes will allow you to create Shim* instances. There is a lot to go over on this subject, but the image Microsoft provides illustrates that the usage of Fakes goes beyond classes out of your control (it includes components within your control as well). Notice how the component you are testing (OrderViewModel) should be isolated from System.dll (i.e. DateTime.Now), other components (PaymentViewModel), and external items as well (if you relied on a Database or Web Service). The Shim is for faking classes, whereas the Stub is for faking (mocking) interfaces. Once you add a Fakes assembly, simply use the ShimPaymentViewModel class to provide the behavior you expect that it should. If, for whatever reason, the real PaymentViewModel class misbehaves and your application crashes you can at least be assured that the problem was not due to the OrderViewModel. Of course, to avoid that you should include some unit tests for PaymentViewModel to ensure that it behaves properly regardless of what other classes are utilizing it or how they are utilizing it. TL;DR; Yes, completely isolate your component when it comes to testing by taking advantage of Microsoft Fakes. Oh, and Microsoft Fakes does play nicely with other frameworks, so don't feel like that by using it that you are foregoing other options; it works in conjunction with other frameworks.
Unit Testing with AOP/PostSharp
I'm trying to use PostSharp to implement a security aspect in order to apply method level authorisation checks in my repository layer. The concept is outlined here. However these authorisation checks are getting in the way during unit testing, making them more into integration tests. What would be the best way to isolate these as unit tests, essentially ignoring/mocking the security aspect so that I can just test the actual class behaviour without the need to initialise a bunch of security information? Does AOP inherently conflict with unit testing?
To answer your 2nd question first, no, AOP doesn’t inherently conflict with unit testing. Usually I’d say it’s best to unit test the methods and the aspects separately. In your case, there are several options. The easiest is simply to have the unit test setup method make sure the thread has the required permissions. If you don’t want to do that, there are two ways you could separate things out for your unit test. The first is to extract all the code from the methods that you are applying security aspects to into separate methods like this: [SecurityAspect] void DoSomething() { DoSomethingInternal(); } void DoSomethingInternal() { // this is the real code } Then you can run your unit tests against all the unsecured ‘internal’ methods – which tests the logic in them without worrying about security. The second approach would be to inject a mock permissions tester into the aspect itself. To be able to do this, you would have to define a separate class and interface that does the actual logic of testing the security, something like this (assuming it’s a Thread that you pass in to verify the security): public interface IPermissionsChecker { bool HasPermissions(Thread thread); } This is your permissions checker for your live system: public class RealPermissionsChecker : IPermissionsChecker { public bool HasPermissions(Thread thread) { // do your real work here } } And this is the one you’ll use in your unit tests public class MockPermissionsChecker : IPermissionsChecker { public bool HasPermissions(Thread thread) { return true; } } Now you need to define your aspect something like this: public class SecurityChecker : OnMethodBoundaryAspect { IPermissionsChecker _checker; public override void OnEntry(MethodExecutionArgs args) { if (!_checker.HasPermissions(Thread.CurrentThread)) throw new SecurityException("No permissions"); } } The only remaining issue is the need to inject the correct permissions checker into the aspect. The slightly hacky way I've done this before is to make _checker a static field, and provide a static method to initialize it: public class SecurityChecker : OnMethodBoundaryAspect { private static IPermissionsChecker _checker; public static void InjectChecker(IPermissionsChecker checker) { // best put some code here to make sure this is only called once, // as well as doing thread synchronization if (_checker == null) _checker = checker; } The fact that InjectChecker is static means you can access it from your app startup (or unit test startup) code. I suspect unit test purists would frown on this - and you do have to make sure you do call it at app startup, but I think it is the simplest way to inject the checker into the aspect, circumventing the fact that the rest of your code can't directly access instances of the aspect. The more complicated alternative is to override RunTimeInitialize() in your aspect - this method is called by PostSharp when the aspect is initialized. You'd probably do something like this: public override void RuntimeInitialize(MethodBase method) { base.RuntimeInitialize(); this._checker =PermissionsCheckerProvider.Current.GetChecker(); } You'll see that requires you to define another class: public class PermissionsCheckerProvider { // make sure you set this at app startup, either to the mock or to the real checker public static PermissionsCheckerProvider Current { get; set;} public IPermissionsChecker GetChecker() { } } This approach guarantees that the method will attempt its initialization at the right time, but then you have the problem of making sure you have supplied an appropriate current provider before the aspect attempts to initialize. So I personally would probably go for the first approach to keep things simple. There's some discussion about dependency injection and RuntimeInitialize here. https://codereview.stackexchange.com/questions/20341/inject-dependency-into-postsharp-aspect
Two links that extensively answer your question: Recording of a webinar on the subject, with two different opinions: Matt Groves and myself Official PostSharp documentation about testing of aspects
If you are using Typemock in your unit tests you can use something like MyAspect myAspectMock = Isolate.Fake.Instance<MyAspect>(Members.MustSpecifyReturnValues); Isolate.Swap.AllInstances<MyAspect>().With(myAspectMock); This allows you to control what tests the aspects are used on, and which ones are not, allowing you to test the method itself, and with the advices applied. Presumably there would be a similar mechanism with other mocking frameworks
Making a private method public to unit test it...good idea?
Moderator Note: There are already 39 answers posted here (some have been deleted). Before you post your answer, consider whether or not you can add something meaningful to the discussion. You're more than likely just repeating what someone else has already said. I occasionally find myself needing to make a private method in a class public just to write some unit tests for it. Usually this would be because the method contains logic shared between other methods in the class and it's tidier to test the logic on its own, or another reason could be possible be I want to test logic used in synchronous threads without having to worry about threading problems. Do other people find themselves doing this, because I don't really like doing it?? I personally think the bonuses outweigh the problems of making a method public which doesn't really provide any service outside of the class... UPDATE Thanks for answers everyone, seems to have piqued peoples' interest. I think the general consensus is testing should happen via the public API as this is the only way a class will ever be used, and I do agree with this. The couple of cases I mentioned above where I would do this above were uncommon cases and I thought the benefits of doing it was worth it. I can however, see everyones point that it should never really happen. And when thinking about it a bit more I think changing your code to accommodate tests is a bad idea - after all I suppose testing is a support tool in a way and changing a system to 'support a support tool' if you will, is blatant bad practice.
Note: This answer was originally posted for the question Is unit testing alone ever a good reason to expose private instance variables via getters? which was merged into this one, so it may be a tad specific to the usecase presented there. As a general statement, I'm usually all for refactoring "production" code to make it easier to test. However, I don't think that would be a good call here. A good unit test (usually) shouldn't care about the class' implementation details, only about its visible behavior. Instead of exposing the internal stacks to the test, you could test that the class returns the pages in the order you expect it to after calling first() or last(). For example, consider this pseudo-code: public class NavigationTest { private Navigation nav; #Before public void setUp() { // Set up nav so the order is page1->page2->page3 and // we've moved back to page2 nav = ...; } #Test public void testFirst() { nav.first(); assertEquals("page1", nav.getPage()); nav.next(); assertEquals("page2", nav.getPage()); nav.next(); assertEquals("page3", nav.getPage()); } #Test public void testLast() { nav.last(); assertEquals("page3", nav.getPage()); nav.previous(); assertEquals("page2", nav.getPage()); nav.previous(); assertEquals("page1", nav.getPage()); } }
Personally, I'd rather unit test using the public API and I'd certainly never make the private method public just to make it easy to test. If you really want to test the private method in isolation, in Java you could use Easymock / Powermock to allow you to do this. You have to be pragmatic about it and you should also be aware of the reasons why things are difficult to test. 'Listen to the tests' - if it's difficult to test, is that telling you something about your design? Could you refactor to where a test for this method would be trivial and easily covered by testing through the public api? Here's what Michael Feathers has to say in 'Working Effectively With Legacy Code" "Many people spend a lot of time trying ot figure out how to get around this problem ... the real answer is that if you have the urge to test a private method, the method shouldn't be private; if making the method public bothers you, chances are, it is because it is part of a separate reponsibility; it should be on another class." [Working Effectively With Legacy Code (2005) by M. Feathers]
As others have said, it is somewhat suspect to be unit testing private methods at all; unit test the public interface, not the private implementation details. That said, the technique I use when I want to unit test something that is private in C# is to downgrade the accessibility protection from private to internal, and then mark the unit testing assembly as a friend assembly using InternalsVisibleTo. The unit testing assembly will then be allowed to treat the internals as public, but you don't have to worry about accidentally adding to your public surface area.
Lots of answers suggest only testing the public interface, but IMHO this is unrealistic - if a method does something that takes 5 steps, you'll want to test those five steps separately, not all together. This requires testing all five methods, which (other than for testing) might otherwise be private. The usual way of testing "private" methods is to give every class its own interface, and make the "private" methods public, but not include them in the interface. This way, they can still be tested, but they don't bloat the interface. Yes, this will result in file- and class-bloat. Yes, this does make the public and private specifiers redundant. Yes, this is a pain in the ass. This is, unfortunately, one of the many sacrifices we make to make code testable. Perhaps a future language (or a even a future version of C#/Java) will have features to make class- and module-testability more convenient; but in the meanwhile, we have to jump through these hoops. There are some who would argue that each of those steps should be its own class, but I disagree - if they all share state, there is no reason to create five separate classes where five methods would do. Even worse, this results in file- and class-bloat. Plus, it infects the public API of your module - all those classes must necessarily be public if you want to test them from another module (either that, or include the test code in the same module, which means shipping the test code with your product).
A unit test should test the public contract, the only way how a class could be used in other parts of the code. A private method is implementation details, you should not test it; as far as public API works correctly, the implementation doesn't matter and could be changed without changes in test cases.
IMO, you should write your tests not making deep assumptions on how your class implemented inside. You probably want to refactor it later using another internal model but still making the same guarantees that previous implementation gives. Keeping that in mind I suggest you to focus on testing that your contract is still holds no matter what internal implementation your class currently have. Property based testing of your public APIs.
How about making it package private? Then your test code can see it (and other classes in your package as well), but it is still hidden from your users. But really, you should not be testing private methods. Those are implementation details, and not part of the contract. Everything they do should be covered by calling the public methods (if they have code in there that is not exercised by the public methods, then that should go). If the private code is too complex, the class is probably doing too many things and in want of refactoring. Making a method public is big commitment. Once you do that, people will be able to use it, and you cannot just change them anymore.
Update: I have added a more expanded and more complete answer to this question in numerous other places. This is can be found on my blog. If I ever need to make something public to test it, this usually hints that the system under test is not following the Single Reponsibility Principle. Hence there is a missing class that should be introduced. After extracting the code into a new class, make it public. Now you can test easily, and you are following SRP. Your other class simply has to invoke this new class via composition. Making methods public/using langauge tricks such as marking code as visible to test assembilies should always be a last resort. For example: public class SystemUnderTest { public void DoStuff() { // Blah // Call Validate() } private void Validate() { // Several lines of complex code... } } Refactor this by introducing a validator object. public class SystemUnderTest { public void DoStuff() { // Blah validator.Invoke(..) } } Now all we have to do is test that the validator is invoked correctly. The actual process of validation (the previously private logic) can be tested in pure isolation. There will be no need for complex test set up to ensure this validation passes.
Some great answers. One thing I didn't see mentioned is that with test-driven development (TDD), private methods are created during the refactoring phase (look at Extract Method for an example of a refactoring pattern), and should therefore already have the necessary test coverage. If done correctly (and of course, you're going to get a mixed bag of opinions when it comes to correctness), you shouldn't have to worry about having to make a private method public just so that you can test it.
If you are using C# you can make method internal. That way you don't pollute public API. Then add attribute to dll [assembly: InternalsVisibleTo("MyTestAssembly")] Now all the methods are visible in your MyTestAssembly project. Maybe not perfect, but better then making private method public just to test it.
Why not split out the stack management algorithm into a utility class? The utility class can manage the stacks and provide public accessors. Its unit tests can be focussed on implementation detail. Deep tests for algorithmically tricky classes are very helpful in wrinkling out edge cases and ensuring coverage. Then your current class can cleanly delegate to the utility class without exposing any implementation details. Its tests will relate to the pagination requirement as others have recommended.
In java, there's also the option of making it package private (ie leaving off the visibility modifier). If your unit tests are in the same package as the class being tested it should then be able to see these methods, and is a bit safer than making the method completely public.
Private methods are usually used as "helper" methods. Therefore they only return basic values and never operate on specific instances of objects. You have a couple of options if you want to test them. Use reflection Give the methods package access Alternatively you could create a new class with the helper method as a public method if it is a good enough candidate for a new class. There is a very good article here on this.
Use reflection to access the private variables if you need to. But really, you don't care about the internal state of the class, you just want to test that the public methods return what you expect in the situations you can anticipate.
In your update you say that it's good to just test using the public API. There is actually two schools here. Black box testing The black box school says that the class should be considered as a black box that no one can see the implementation inside it. The only way to test this is through the public API -- just like the user's of the class will be using it. white box testing. The white box school thinks it naturally to use the knowledge about the implementation of the class and then test the class to know that it works as it should. I really cannot take side in the discussion. I just thought it would be interesting to know that there are two distinct ways to test a class (or a library or whatever).
in terms of unit testing, you should definitely not add more methods; I believe you would better make a test case just about your first() method, which would be called before each test; then you can call multiple times the - next(), previous() and last() to see if the outcomes match your expectation. I guess if you don't add more methods to your class (just for testing purposes), you would stick to the "black box" principle of testing;
You should never ever ever let your tests dictate your code. I'm not speaking about TDD or other DDs I mean, exactly what your asking. Does your app need those methods to be public. If it does then test them. If it does not then then don't make them public just for testing. Same with variables and others. Let your application's needs dictate the code, and let your tests test that the need is met. (Again I don't mean testing first or not I mean changing a classes structure to meet a testing goal). Instead you should "test higher". Test the method that calls the private method. But your tests should be testing your applications needs and not your "implementation decisions". For example (bod pseudo code here); public int books(int a) { return add(a, 2); } private int add(int a, int b) { return a+b; } There is no reason to test "add" you can test "books" instead. Never ever let your tests make code design decisions for you. Test that you get the expected result, not how you get that result.
I would say it is a bad idea for I am not sure whether you get any benefit and potentially problems down the line. If you are changing the contract of a calls, just to test a private method, you're not testing the class in how it would be used, but creating an artificial scenario which you never intended to happen. Furthermore, by declaring the method as public, what's to say that in six months time (after forgetting that the only reason for making a method public is for testing) that you (or if you've handed the project over) somebody completely different won't use it, leading to potentially unintended consequences and/or a maintenance nightmare.
First see if the method ought to be extracted into another class and made public. If that's not the case, make it package protected and in Java annotate with #VisibleForTesting.
Private methods that you want to test in isolation are an indication that there's another "concept" buried in your class. Extract that "concept" to its own class and test it as a separate "unit". Take a look at this video for a really interesting take on the subject.
There are actually situations when you should do this (e.g. when you're implementing some complex algorithms). Just do it package-private and this will be enough. But in most cases probably you have too complex classes which requires factoring out logic into other classes.
I tend to agree that the bonuses of having it unit tested outweigh the problems of increasing the visibility of some of the members. A slight improvement is to make it protected and virtual, then override it in a test class to expose it. Alternatively, if it's functionality you want to test separately does it not suggest a missing object from your design? Maybe you could put it in a separate testable class...then your existing class just delegates to an instance of this new class.
I generally keep the test classes in the same project/assembly as the classes under test. This way I only need internal visibility to make functions/classes testable. This somewhat complicates your building process, which needs to filter out the test classes. I achieve this by naming all my test classes TestedClassTest and using a regex to filter those classes. This of course only applies to the C# / .NET part of your question
I will often add a method called something like validate, verify, check, etc, to a class so that it can be called to test the internal state of an object. Sometimes this method is wrapped in an ifdef block (I write mostly in C++) so that it isn't compiled for release. But it's often useful in release to provide validation methods that walk the program's object trees checking things.
Guava has a #VisibleForTesting annotation for marking methods that have enlarged scope (package or public) that they would otherwise. I use a #Private annotation for the same thing. While the public API must be tested, sometimes it's convenient and sensible to get at stuff that wouldn't normally be public. When: a class is made significantly less readable, in toto, by breaking it up into multiple classes, just to make it more testable, and providing some test access to the innards would do the trick it seems like religion is trumping engineering.
I usually leave those methods as protected and place the unit test within the same package (but in another project or source folder), where they can access all the protected methods because the class loader will place them within the same namespace.
No, because there are better ways of skinning that cat. Some unit test harnesses rely on macros in the class definition which automagically expand to create hooks when built in test mode. Very C style, but it works. An easier OO idiom is to make anything you want to test "protected" rather than "private". The test harness inherits from the class under test, and can then access all protected members. Or you go for the "friend" option. Personally this is the feature of C++ I like least because it breaks the encapsulation rules, but it happens to be necessary for how C++ implements some features, so hey ho. Anyway, if you're unit testing then you're just as likely to need to inject values into those members. White box texting is perfectly valid. And that really would break your encapsulation.
In .Net there is a special class called PrivateObject deigned specifically to allow you to access private methods of a class. See more about it on the MSDN or here on Stack Overflow (I am wondering that no one has mentioned it so far.) There are situations though which this is not enough, in which case you will have to use reflection. Still I would adhere to the general recommendation not to test private methods, however as usual there are always exceptions.
Very answered question. IHMO, the excellent answer from #BlueRaja - Danny Pflughoeft is one of the best. Lots of answers suggest only testing the public interface, but IMHO this is unrealistic - if a method does something that takes 5 steps, you'll want to test those five steps separately, not all together. This requires testing all five methods, which (other than for testing) might otherwise be private. Above all, I want to stress that the question "should we make a private method public to unit test it" is a question which an objectively correct answer depends on multiple parameters. So I think that in some cases we have not to and in others we should. Making public a private method or extracting the private method as a public method in another class (new or existing)? It is rarely the best way. A unit test has to test the behavior of one API method/function. If you test a public method that invokes another public method belonging to the same component, you don't unit test the method. You test multiple public methods at the same time. As a consequence, you may duplicate tests, test fixtures, test assertions, the test maintenance and more generally the application design. As the tests value decreases, they often lose interest for developers that write or maintain them. To avoid all this duplication, instead of making the private method public method, in many cases a better solution is extracting the private method as a public method in a new or an existing class. It will not create a design defect. It will make the code more meaningful and the class less bloat. Besides, sometimes the private method is a routine/subset of the class while the behavior suits better in a specific structure. At last, it also makes the code more testable and avoid tests duplication. We can indeed prevent tests duplication by unit testing the public method in its own test class and in the test class of the client classes, we have just to mock the dependency. Mocking private methods? While it is possible by using reflection or with tools as PowerMock, I think that it is often a way to bypass a design issue. A private member is not designed to be exposed to other classes. A test class is a class as another. So we should apply the same rule for it. Mocking public methods of the object under test? You may want to change the modifier private to public to test the method. Then to test the method that uses this refactored public method, you may be tempted to mock the refactored public method by using tools as Mockito (spy concept) but similarly to mocking private methods, we should avoid to mock the object under test. The Mockito.spy() documentation says it itself : Creates a spy of the real object. The spy calls real methods unless they are > > stubbed. Real spies should be used carefully and occasionally, for example when dealing with legacy code. By experience, using spy() generally decreases the test quality and its readability. Besides, it is much more error-prone as the object under test is both a mock and a real object. It is often the best way to write an invalid acceptance test. Here is a guideline I use to decide whether a private method should stay private or be refactored. Case 1) Never make a private method public if this method is invoked once. It is a private method for a single method. So you could never duplicate test logic as it is invoke once. Case 2) You should wonder whether a private method should be refactored as a public method if the private method is invoked more than once. How to decide ? The private method doesn't produce duplication in the tests. -> Keep the method private as it is. The private method produces duplication in the tests. That is, you need to repeat some tests, to assert the same logic for each test that unit-tests public methods using the private method. -> If the repeated processing may make part of the API provided to clients (no security issue, no internal processing, etc...), extract the private method as a public method in a new class. -> Otherwise, if the repeated processing has not to make part of the API provided to clients (security issue, internal processing, etc...), don't widen the visibility of the private method to public. You may leave it unchanged or move the method in a private package class that will never make part of the API and would be never accessible by clients. Code examples The examples rely on Java and the following libraries : JUnit, AssertJ (assertion matcher) and Mockito. But I think that the overall approach is also valid for C#. 1) Example where the private method doesn't create duplication in the test code Here is a Computation class that provides methods to perform some computations. All public methods use the mapToInts() method. public class Computation { public int add(String a, String b) { int[] ints = mapToInts(a, b); return ints[0] + ints[1]; } public int minus(String a, String b) { int[] ints = mapToInts(a, b); return ints[0] - ints[1]; } public int multiply(String a, String b) { int[] ints = mapToInts(a, b); return ints[0] * ints[1]; } private int[] mapToInts(String a, String b) { return new int[] { Integer.parseInt(a), Integer.parseInt(b) }; } } Here is the test code : public class ComputationTest { private Computation computation = new Computation(); #Test public void add() throws Exception { Assert.assertEquals(7, computation.add("3", "4")); } #Test public void minus() throws Exception { Assert.assertEquals(2, computation.minus("5", "3")); } #Test public void multiply() throws Exception { Assert.assertEquals(100, computation.multiply("20", "5")); } } We could see that the invocation of the private method mapToInts() doesn't duplicate the test logic. It is an intermediary operation and it doesn't produce a specific result that we need to assert in the tests. 2) Example where the private method creates undesirable duplication in the test code Here is a MessageService class that provides methods to create messages. All public methods use the createHeader() method : public class MessageService { public Message createMessage(String message, Credentials credentials) { Header header = createHeader(credentials, message, false); return new Message(header, message); } public Message createEncryptedMessage(String message, Credentials credentials) { Header header = createHeader(credentials, message, true); // specific processing to encrypt // ...... return new Message(header, message); } public Message createAnonymousMessage(String message) { Header header = createHeader(Credentials.anonymous(), message, false); return new Message(header, message); } private Header createHeader(Credentials credentials, String message, boolean isEncrypted) { return new Header(credentials, message.length(), LocalDate.now(), isEncrypted); } } Here is the test code : import java.time.LocalDate; import org.assertj.core.api.Assertions; import org.junit.Test; import junit.framework.Assert; public class MessageServiceTest { private MessageService messageService = new MessageService(); #Test public void createMessage() throws Exception { final String inputMessage = "simple message"; final Credentials inputCredentials = new Credentials("user", "pass"); Message actualMessage = messageService.createMessage(inputMessage, inputCredentials); // assertion Assert.assertEquals(inputMessage, actualMessage.getMessage()); Assertions.assertThat(actualMessage.getHeader()) .extracting(Header::getCredentials, Header::getLength, Header::getDate, Header::isEncryptedMessage) .containsExactly(inputCredentials, 9, LocalDate.now(), false); } #Test public void createEncryptedMessage() throws Exception { final String inputMessage = "encryted message"; final Credentials inputCredentials = new Credentials("user", "pass"); Message actualMessage = messageService.createEncryptedMessage(inputMessage, inputCredentials); // assertion Assert.assertEquals("Aç4B36ddflm1Dkok49d1d9gaz", actualMessage.getMessage()); Assertions.assertThat(actualMessage.getHeader()) .extracting(Header::getCredentials, Header::getLength, Header::getDate, Header::isEncryptedMessage) .containsExactly(inputCredentials, 9, LocalDate.now(), true); } #Test public void createAnonymousMessage() throws Exception { final String inputMessage = "anonymous message"; Message actualMessage = messageService.createAnonymousMessage(inputMessage); // assertion Assert.assertEquals(inputMessage, actualMessage.getMessage()); Assertions.assertThat(actualMessage.getHeader()) .extracting(Header::getCredentials, Header::getLength, Header::getDate, Header::isEncryptedMessage) .containsExactly(Credentials.anonymous(), 9, LocalDate.now(), false); } } We could see that the invocation of the private method createHeader() creates some duplication in the test logic. createHeader() creates indeed a specific result that we need to assert in the tests. We assert 3 times the header content while a single assertion should be required. We could also note that the asserting duplication is close between the methods but not necessary the same as the private method has a specific logic : Of course, we could have more differences according to the logic complexity of the private method. Besides, at each time we add a new public method in MessageService that calls createHeader(), we will have to add this assertion. Note also that if createHeader() modifies its behavior, all these tests may also need to be modified. Definitively, it is not a very good design. Refactoring step Suppose we are in a case where createHeader() is acceptable to make part of the API. We will start by refactoring the MessageService class by changing the access modifier of createHeader() to public : public Header createHeader(Credentials credentials, String message, boolean isEncrypted) { return new Header(credentials, message.length(), LocalDate.now(), isEncrypted); } We could now test unitary this method : #Test public void createHeader_with_encrypted_message() throws Exception { ... boolean isEncrypted = true; // action Header actualHeader = messageService.createHeader(credentials, message, isEncrypted); // assertion Assertions.assertThat(actualHeader) .extracting(Header::getCredentials, Header::getLength, Header::getDate, Header::isEncryptedMessage) .containsExactly(Credentials.anonymous(), 9, LocalDate.now(), true); } #Test public void createHeader_with_not_encrypted_message() throws Exception { ... boolean isEncrypted = false; // action messageService.createHeader(credentials, message, isEncrypted); // assertion Assertions.assertThat(actualHeader) .extracting(Header::getCredentials, Header::getLength, Header::getDate, Header::isEncryptedMessage) .containsExactly(Credentials.anonymous(), 9, LocalDate.now(), false); } But what about the tests we write previously for public methods of the class that use createHeader() ? Not many differences. In fact, we are still annoyed as these public methods still need to be tested concerning the returned header value. If we remove these assertions, we may not detect regressions about it. We should be able to naturally isolate this processing but we cannot as the createHeader() method belongs to the tested component. That's why I explained at the beginning of my answer that in most of cases, we should favor the extraction of the private method in another class to the change of the access modifier to public. So we introduce HeaderService : public class HeaderService { public Header createHeader(Credentials credentials, String message, boolean isEncrypted) { return new Header(credentials, message.length(), LocalDate.now(), isEncrypted); } } And we migrate the createHeader() tests in HeaderServiceTest. Now MessageService is defined with a HeaderService dependency: public class MessageService { private HeaderService headerService; public MessageService(HeaderService headerService) { this.headerService = headerService; } public Message createMessage(String message, Credentials credentials) { Header header = headerService.createHeader(credentials, message, false); return new Message(header, message); } public Message createEncryptedMessage(String message, Credentials credentials) { Header header = headerService.createHeader(credentials, message, true); // specific processing to encrypt // ...... return new Message(header, message); } public Message createAnonymousMessage(String message) { Header header = headerService.createHeader(Credentials.anonymous(), message, false); return new Message(header, message); } } And in MessageService tests, we don't need any longer to assert each header value as this is already tested. We want to just ensure that Message.getHeader() returns what HeaderService.createHeader() has returned. For example, here is the new version of createMessage() test : #Test public void createMessage() throws Exception { final String inputMessage = "simple message"; final Credentials inputCredentials = new Credentials("user", "pass"); final Header fakeHeaderForMock = createFakeHeader(); Mockito.when(headerService.createHeader(inputCredentials, inputMessage, false)) .thenReturn(fakeHeaderForMock); // action Message actualMessage = messageService.createMessage(inputMessage, inputCredentials); // assertion Assert.assertEquals(inputMessage, actualMessage.getMessage()); Assert.assertSame(fakeHeaderForMock, actualMessage.getHeader()); } Note the assertSame() use to compare the object references for the headers and not the contents. Now, HeaderService.createHeader() may change its behavior and return different values, it doesn't matter from the MessageService tests point of view.
The point of the unit test is to confirm the workings of the public api for that unit. There should be no need to make a private method exposed only for testing, if so then your interface should be rethought. Private methods can be thought as 'helper' methods to the public interface and therefore are tested via the public interface as they would be calling into the private methods. The only reason I can see that you have a 'need' to do this is that your class is not properly designed for testing in mind.
Mock .NET classes using wrapper classes
I have a class that takes a MethodInfo instance and extracts some information from it, but I would like to mock this class. At the moment it is difficult because it takes a MethodInfo, so my plan was to create a wrapper for the MethodInfo class and implement an interface on it. For example: public interface IMethodInfo { string Name { get; } } public class MethodInfoProxy : IMethodInfo { private readonly MethodInfo _method; public MethodInfoProxy(MethodInfo method) { _method = method; } public string Name { get { return _method.Name; } } } public class MyClass { public MyClass(IMethodInfo method) { ... } } Another example would be the File.Exists method. The thought would be to create a IFile.Exists and put it on a FileProxy class that would simply delegate to File.Exists. As I'm new to the whole unit testing world I would like to know if this would be considered a good approach to take?
You have two options here: Use a mocking framework like Microsoft Moles or TypeMock Isolator that can mock static and sealed classes. This is great because you don't end up changing your code just to isolate the code under test from its dependencies. Defining interfaces for behaviours that you want to mock, and then creating a default implementation that wraps a static call, or other difficult-to-test api. This is the approach you've suggested and one that I've used a lot. The key thing, when defining these interfaces is to pass the real/mock implementation of the interface into the test class via some form of dependency injection - usually constructor injection. Some people make the mistake of constructing the object within the class being tested and that makes it impossible to test. A good rule of thumb is that when you see objects being constructed in your business code, then that is a code smell - not always a bad thing, but definitely something to view with suspicion. There's a great video about this stuff: The Clean Code Talks - "Global State and Singletons". There's a bit of a religious war between those who think testing shouldn't change the code and those that think it should. Dependency injection, which is essential if you are going to mock by creating interfaces, leads to code with high cohesion and loose coupling and an intuitive API. But the other approach isn't precluded from these benefits - it's just not so automatic.
I recommend trying to pull the dependencies out of the class - instead of supplying a MethodInfo (or a proxy), just supply the Name. When that isn't practical, you can either write proxy classes that use an adapter interface (as you've suggested) or use a black-magic tool like TypeMock or Moles (just kidding about the black magic part: I just don't have any experience with them). If you plan to use the proxy approach, be sure to take a look at the SystemWrapper library, which already handles about twenty classes from the .NET framwork.
You could create a wrapper around each of the class that you use but it would be extremely expensive. It's better to use a mocking framework such as the moles framework by Microsoft http://research.microsoft.com/en-us/projects/pex/ which can also stub out static methods.
A Mock class (or a fake class) would be a class you make to satisfy dependencies and make your test more deterministic by ruling out problems in your dependencies. public interface IMethodInfo { string Name { get; } } Your mock class: FakeMethodInfo : IMethodInfo { string Name {get {return "FakeMethod";}} } Now, in your unit test, pass the FakeMethodInfo class where you need an IMethodInfo. The whole purpose is that you know FakeMethodInfo just returns a string so if something fails, it is not the problem. Don't know what context MethodInfo has in your program. A better example would be interface IUser { string UserName {get;} } If it were implemented in a class you would get the actual username from a data base. Now, if you make a fake one, and pass it around, you kinda simulate a user logged in without a real user, and you rule out that any problem has to do with `IUser. See this large answer I posted on why you would use mocking. And an example with Moq.: Difference between Dependency Injection and Mocking framework (Ninject vs RhinoMock or Moq)
For faster creating of wrapper classes, you can use one of the Scaffold code generator I created. https://www.nuget.org/packages/Digitrish.WrapperGenerator/ This will generate Interface that you can use to any mocking framework and concrete wrapper class for the real implementation.
NUnit testing the application, not the environment or database
I want to be better at using NUnit for testing the applications I write, but I often find that the unit tests I write have a direct link to the environment or underlying database on the development machine instead. Let me make an example. I'm writing a class which has the single responsibility of retriving a string, which has been stored in the registry by another application. The key is stored in HKCU\Software\CustomApplication\IniPath. The Test I end up writing looks like this; [Test] public void GetIniDir() { RegistryReader r = new RegistryReader(); Assert.AreEqual(#"C:\Programfiles\CustomApplication\SomeDir", r.IniDir); } But the problem here is that the string #"C:\Programfiles\CustomApplication\SomeDir" is really just correct right now. Tomorrow it might have changed to #"C:\Anotherdir\SomeDir", and suddenly that breaks my unit tests, even though the code hasn't changed. This problem is also seen when I create a class which does CRUD operations against a database. The data in the database can change all the time, and this in turn makes the tests fail. So even if my class does what it is intended to do it will fail because the database returns more customers that it had when I originally wrote the test. [Test] public void GetAllCustomersCount() { DAL d = new DAL(); Assert.AreEqual(249, d.GetCustomerCount()); } Do you guys have any tips on writing Tests which do not rely on the surrounding environment as much?
The solution to this problem is well-known: mocking. Refactor your code to interfaces, then develop fake classes to implement those interfaces or mock them with a mocking framework, such as RhinoMocks, easyMock, Moq, et. al. Using fake or mock classes allow you to define what the interface returns for your test without having to actually interact with the external entity, such as a database. For more info on mocking via SO, try this Google search: http://www.google.com/search?q=mock+site:stackoverflow.com. You may also be interesting in the definitions at: What's the difference between faking, mocking, and stubbing? Additionally, good development practices, such as dependency injection (as #Patrik suggests), which allows the decoupling of your classes from its dependencies, and the avoidance of static objects, which makes unit testing harder, will facilitate your testing. Using TDD practices -- where the tests are developed first -- will help you to naturally develop applications that incorporate these design principles.
The easiest way is to make the dependencies explicit using dependency injection. For example, your first example has a dependency on the registry, make this dependency explicit by passing an IRegistry (an interface that you'll define) instance and then only use this passed in dependency to read from the registry. This way you can pass in an IRegistry-stub when testing that always return a known value, in production you instead use an implementation that actually reads from the registry. public interface IRegistry { string GetCurrentUserValue(string key); } public class RegistryReader { public RegistryReader(IRegistry registry) { ... // make the dependency explicit in the constructor. } } [TestFixture] public class RegistryReaderTests { [Test] public void Foo_test() { var stub = new StubRegistry(); stub.ReturnValue = "known value"; RegistryReader testedReader = new RegistryReader(stub); // test here... } public class StubRegistry : IRegistry { public string ReturnValue; public string GetCurrentUserValue(string key) { return ReturnValue; } } } In this quick example i use manual stubbing, of course you could use any mocking framework for this.
Other way is to create separate database for tests.
You should read up on the inversion of control principle and how to use the dependency injection technique - that really helps you write testable code. In your case, you should probably have an interface - e.g. IIniDirProvider - which is implemented by RegistryBasedIniDirProvider, which is resposible for providing the initial directory based off a specific key in the registry. Then, when some other class needs to look up the initial directory, that other class should have the following ctor: public SomeOtherClass(IIniDirProvider iniDirProvider) { this.iniDirProvider = iniDirProvider; } -allowing you to pass in a mock IIniDirProvider when you need to unit test SomeOtherClass. That way your unit test will not depend on anything being present in the registry.