What should you do about nested ViewModels when you are unit testing? - c#

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.

Related

Adding Virtual Keyword When Testing Legacy Code

I am adding tests to some gnarly legacy code in order to have confidence enough to seriously refactor it. One of the issues is that whoever wrote the code obviously made no attempt to make the code testable (given that they never wrote a single unit test!)
A common issue is that there are currently no interfaces, just an 11-level-deep inheritance chain. I am using Rhino Mocks to isolate the class under test from its dependencies, but as I am mocking a class, not an interface, I can only stub a read-only property if it has the virtual keyword.
My current thinking is that I will just add the virtual keyword to the property. There is no plan to add any further objects into the existing dependency chain and it will allow the tests to be written.
Are the any arguments against adding the virtual keyword, or is this an acceptable compromise in order to get tests in?
Example code...
In the test class:
var someClassStub = MockRepository.GenerateStub<SomeClass>();
someClassStub.Stub(s => s.SomeProperty).Return("Test");
In SomeClass:
public virtual string SomeProperty {
get {
return someDependency.SomeMethod();
}
}
The primary argument against adding virtual is that it misrepresents your intentions. The virtual keyword signals to derived classes that you expect this property may be overridden.
I would not use virtual, but mock the dependency like the following:
var mockedDependency = MockRepository.GenerateMock<IDependency>();
mockedDependency.Expect(x => x.SomeMethod())
.Returns("whatever your test dictates");
var target = new SomeClass(mockedDependency);
mockedDependency.VerifyAllExpectations();
Then inject that into a newly created overloaded constructor, like the following:
public SomeClass(IDependency dependency) : base()
{
this.someDependency = dependency;
}
Instead of adding virtual everywhere, there a few safer methods of making your code initially testable. Personally, I'd highly recommend using the "Extract Interface" tool provided with Visual Studio and replace concrete class references with the interface where possible to do safely. Then, mock the interface instead of the concrete class.
If you're using a version of Visual Studio(or some other IDE) that doesn't support Extract Interface, all you have to do is track down all the public members of the class and add them to an interface and make your concrete class implement it.
Your first priority should be getting that initial set of tests. This way you can later make more dangerous changes with reasonable certainty that your code isn't broken.
For anyone working on making old legacy code unit testable, I'd highly recommend reading the book Working Effectively With Legacy Code. It is well worth the money. So much so that my manager ended up buying my office a copy to consult.

Unit test a method which is on high abstraction level

A similar topic has been discussed in The value of high level unit tests and mock objects
However, I'd like to describe a specific situation and ask your opinion about how I should write a unit test.
I am developing an ordinary 3-tier application, which uses Entity Framework. Above EF, I have two layers:
Repositories: They directly access the EF ObjectContext and do all the CRUD work (actually, these classes are generated with a T4 template). All Repository class has an appropriate interface.
Managers: They implement the higher level business logic, they do not access directly the ObjectContext, rather use an appropriate Repository. Managers do not know the concrete Repository-implementation, only the interface (I use dependency injection, and mocks in the unit test).
Without further description, here is the class I'd like to write unit tests for:
public class PersonManager
{
private IPersonRepository personRepository; // This is injected.
// Constructor for injection is here.
public void ComplexMethod()
{
// High level business logic
bool result = this.SimpleMethod1();
if(result)
this.SimpleMethod2(1);
else
this.SimpleMethod2(2);
}
public bool SimpleMethod1()
{
// Doing some low-level work with the repository.
}
public void SimpleMethod2(int param)
{
// Doing some low-level work with the repository.
}
}
It is really easy to unit test SimpleMethod1 and SimpleMethod2 by instantiating the PersonManager with a mock of the PersonRepository.
But I can not find any convenient way to unit test ComplexMethod.
Do you have any recommendation about how should I do that? Or that should not be unit tested at all? Maybe I should not use the this reference for the method calls in ComplexMethod, rather access the PersonManager itself via an interface, and replace that with a mock too?
Thanks in advance for any advice.
Guillaume's answer is good (+1), but I wanted to give an additional observation. What I see in the code you've posted is the basis for a very common question from people trying to figure out (or argue against) TDD, which is:
"How/why should I test ComplexMethod() since it depends on SimpleMethod1() and SimpleMethod2(), which are already tested and have their own behavior that I'd have to account for in tests of ComplexMethod()? I'd have to basically duplicate all the tests of SimpleMethod1() and SimpleMethod2() in order to fully test ComplexMethod(), and that's just stupid."
Shortly after, they usually find out about partial mocks. Using partial mocks, you could mock SimpleMethod1() and SimpleMethod2() and then test ComplexMethod() using normal mock mechanisms. "Sounds great," they think, "This will solve my problem perfectly!". A good mock framework should strongly discourage using partial mocks in this way, though, because the reality is:
Your tests are telling you about a design problem.
Specifically, they're telling you that you've mixed concerns and/or abstraction levels in one class. They're telling you that SimpleMethod1() and SimpleMethod2() should be extracted to another class which this class depends on. No matter how many times I see this scenario, and no matter how vehemently the developer argues, the tests are proven right in the end 100% of the time.
I don't see what the problem is. You can test your complex method while mocking the repository, there is no problem.
Your would need two unit-tests, each one would use the same sequence of expectations and executions that you have in your tests of the SimpleMethod1 (I assume you already have two unit-tests for SimpleMethod1, one for a return of "true", one for "false") and also the same expectations that you have for your test SimpleMethod2 with a fixed parameter 1, or 2 respectively.
Granted, there would be some "duplication" in your testing class, but that's not a problem.
Also note your tests for SimpleMethod2 should not make any assumption for the parameter passed: in "real-life" you can have only 1 or 2 as a parameter (and that's what your unit-test for ComplexMethod would have), but your unit-tests for SImpleMethod2 should test it whatever the parameter is: any int.
And finally, if ComplexMethod is the ONLY way to call SimpleMethod1 and/or SimpleMethod2, you should consider making these private, and have only unit-tests for ComplexMethod.
Does that make sense?

How can I use unit testing when classes depend on one another or external data?

I'd like to start using unit tests, but I'm having a hard time understanding how I can use them with my current project.
My current project is an application which collects files into a 'Catalog'. A Catalog can then extract information from the files it contains such as thumbnails and other properties. Users can also tag the files with other custom meta data such as "Author" and "Notes". It could easily be compared to a photo album application like Picasa, or Adobe Lightroom.
I've separated the code to create and manipulate a Catalog into a separate DLL which I'd now like to test. However, the majority of my classes are never meant to be instantiated on their own. Instead everything happens through my Catalog class. For example there's no way I can test my File class on its own, as a File is only accessible through a Catalog.
As an alternative to unit tests I think it would make more sense for me to write a test program that run through a series of actions including creating a catalog, re-opening the catalog that was created, and manipulating the contents of the catalog. See the code below.
//NOTE: The real version would have code to log the results and any exceptions thrown
//input data
string testCatalogALocation = "C:\TestCatalogA"
string testCatalogBLocation = "C:\TestCatalogB"
string testFileLocation = "C:\testfile.jpg"
string testFileName = System.IO.Path.GetFileName(testFileLocation);
//Test creating catalogs
Catalog catAtemp = Catalog(testCatalogALocation)
Catalog catBtemp = Catalog(testCatalogBLocation );
//test opening catalogs
Catalog catA = Catalog.OpenCatalog(testCatalogALocation);
Catalog catB = Catalog.OpenCatalog(testCatalogBLocation );
using(FileStream fs = new FileStream(testFileLocation )
{
//test importing a file
catA.ImportFile(testFileName,fs);
}
//test retrieving a file
File testFile = catA.GetFile(System.IO.Path.GetFileName(testFileLocation));
//test copying between catalogs
catB.CopyFileTo(testFile);
//Clean Up after test
System.IO.Directory.Delete(testCatalogALocation);
System.IO.Directory.Delete(testCatalogBLocation);
First, am I missing something? Is there some way to unit test a program like this? Second, is there some way to create a procedural type test like the code above but be able to take advantage of the testing tools building into Visual Studio? Will a "Generic Test" in VS2010 allow me to do this?
Update
Thanks for all the responses everyone. Actually my classes do in fact inherit from a series of interfaces. Here's a class diagram for anyone that is interested. Actually I have more interfaces then I have classes. I just left out the interfaces from my example for the sake of simplicity.
Thanks for all the suggestions to use mocking. I'd heard the term in the past, but never really understood what a "mock" was until now. I understand how I could create a mock of my IFile interface, which represents a single file in a catalog. I also understand how I could create a mock version of my ICatalog interface to test how two catalogs interact.
Yet I don't understand how I can test my concrete ICatalog implementations as they strongly related to their back end data sources. Actual the whole purpose of my Catalog classes is to read, write, and manipulate their external data/resources.
You ought to read about SOLID code principles. In particular the 'D' on SOLID stands for the Dependency Injection/Inversion Principle, this is where the class you're trying to test doesn't depend on other concrete classes and external implementations, but instead depends on interfaces and abstractions. You rely on an IoC (Inversion of Control) Container (such as Unity, Ninject, or Castle Windsor) to dynamically inject the concrete dependency at runtime, but during Unit Testing you inject a mock/stub instead.
For instance consider following class:
public class ComplexAlgorithm
{
protected DatabaseAccessor _data;
public ComplexAlgorithm(DatabaseAccessor dataAccessor)
{
_data = dataAccessor;
}
public int RunAlgorithm()
{
// RunAlgorithm needs to call methods from DatabaseAccessor
}
}
RunAlgorithm() method needs to hit the database (via DatabaseAccessor) making it difficult to test. So instead we change DatabaseAccessor into an interface.
public class ComplexAlgorithm
{
protected IDatabaseAccessor _data;
public ComplexAlgorithm(IDatabaseAccessor dataAccessor)
{
_data = dataAccessor;
}
// rest of class (snip)
}
Now ComplexAlgorithm depends on an interface IDatabaseAccessor which can easily be mocked for when we need to Unit test ComplexAlgorithm in isolation. For instance:
public class MyFakeDataAccessor : IDatabaseAccessor
{
public IList<Thing> GetThings()
{
// Return a fake/pretend list of things for testing
return new List<Thing>()
{
new Thing("Thing 1"),
new Thing("Thing 2"),
new Thing("Thing 3"),
new Thing("Thing 4")
};
}
// Other methods (snip)
}
[Test]
public void Should_Return_8_With_Four_Things_In_Database()
{
// Arrange
IDatabaseAccessor fakeData = new MyFakeDataAccessor();
ComplexAlgorithm algorithm = new ComplexAlgorithm(fakeData);
int expectedValue = 8;
// Act
int actualValue = algorithm.RunAlgorithm();
// Assert
Assert.AreEqual(expectedValue, actualValue);
}
We're essentially 'decoupling' the two classes from each other. Decoupling is another important software engineering principle for writing more maintainable and robust code.
This is really the tip of the tip of the iceberg as far as Dependency Injection, SOLID and Decoupling go, but it's what you need in order to effectively Unit test your code.
Here is a simple algorithm that can help get you started. There are other techniques to decouple code, but this can often get you pretty far, particularly if your code is not too large and deeply entrenched.
Identify the locations where you depend on external data/resources and determine whether you have classes that isolate each dependency.
If necessary, refactor to achieve the necessary insulation. This is the most challenging part to do safely, so focus on the lowest-risk changes first.
Extract interfaces for the classes that isolate external data.
When you construct your classes, pass in the external dependencies as interfaces rather than having the class instantiate them itself.
Create test implementations of your interfaces that don't depend on the external resources. This is also where you can add 'sensing' code for your tests to make sure the appropriate calls are being used. Mocking frameworks can be very helpful here, but it can be a good exercise to create the stub classes manually for a simple project, as it gives you a sense of what your test classes are doing. Manual stub classes typically set public properties to indicate when/how methods are called and have public properties to indicate how particular calls should behave.
Write tests that call methods on your classes, using the stubbed dependencies to sense whether the class is doing the right things in different cases. An easy way to start, if you already have functional code written, is to map out the different pathways and write tests that cover the different cases, asserting the behavior that currently occurs. These are known as characterization tests and they can give you the confidence to start refactoring your code, since now you know you're at least not changing the behavior you've already established.
Best of luck. Writing good unit tests requires a change of perspective, which will develop naturally as you work to identify dependencies and create the necessary isolation for testing. At first, the code will feel uglier, with additional layers of indirection that were previously unnecessarily, but as you learn various isolation techniques and refactor (which you can now do more easily, with tests to support it), you may find that things actually become cleaner and easier to understand.
This is a pure case where Dependency Injection plays a vital role.
As Shady suggest to read about mocking & stubbing. To achive this , you should consider using some Dependency Injectors like ( Unity in .net).
Also read about Dependency Injection Here
http://martinfowler.com/articles/injection.html
the majority of my classes are never
meant to be instantiated on their own
This is where the D - the Design D - comes into TDD. It's bad design to have classes that are tightly coupled. That badness manifests itself immediately when you try to unit test such a class - and if you start with unit tests, you'll never find yourself in this situation. Writing testable code compels us to better design.
I'm sorry; this isn't an answer to your question, but I see others have already mentioned mocking and DI, and those answers are fine. But you put the TDD tag on this question, and this is the TDD answer to your question: don't put yourself in the situation of tightly coupled classes.
What you have now is Legacy Code. That is: code that has been implemented without tests. For your initial tests I would definitely test through the Catalog class until you can break all those dependencies. So your first set of tests will be integration/acceptance tests.
If you don't expect for any behavior to change, then leave it at that, but if you do make a change, I suggest that you TDD the change and build up unit tests with the changes.

Is Typemock the only framework that can mock a Linq To SQL Table class?

I am trying to setup unit tests for my Linq To SQL code. My code uses the System.Data.Linq.Table class (generated by the designer).
Because this class is sealed and the constructor is internal it is completely impervious to unit testing frameworks like Rhino Mocks. (Unless you want to alter you code to use the repository pattern, which I would rather not.)
Typemock can (some how) mock this class. (See here for an example.)
However, Typemock is also $800 a license. I don't see my employer springing for that anytime soon.
So here is the question. Are there any other mocking frameworks out there that don't rely on Interfaces to create the mocks?
Edit: Example of code that I need to test:
public class UserDAL : IUserDAL
{
private IDataClassesDataContext _ctx;
public UserDAL()
{
string env = ConfigurationManager.AppSettings["Environment"];
string connectionString = ConfigurationManager
.ConnectionStrings[env].ConnectionString;
_ctx = new DataClassesDataContext(connectionString);
}
public UserDAL(IDataClassesDataContext context)
{
_ctx = context;
}
public List<User> GetUsersByOrganization(int organizationId)
{
IOrderedQueryable<User> vUsers =
(from myUsers in _ctx.Users
where myUsers.Organization == organizationId
orderby myUsers.LastName
select myUsers);
return vUsers.ToList();
}
public bool IsUserInOrganization(User user, int orgainzationID)
{
// Do some Dal Related logic here.
return GetUsersByOrganization(orgainzationID).Contains(user);
}
}
I have shorted this up to make it easier to read. The idea is that I have some code (like IsUserInOrganization that calls another method (like GetUsersByOrganization) that does a Linq query.
I would like to unit test the IsUserInOrganization method. Do do that I would need to mock _ctx.Users which is a Table class (that is sealed and has an internal constructor).
Check out Microsoft Stubs that has the simple premise of:
Replace any .NET method with your own
delegate!
And a more detailed description of it's capabilities (emphasis is mine).
Stubs is a lightweight framework for
test stubs and detours in .NET that is
entirely based on delegates, type
safe, refactorable and source code
generated. Stubs was designed provide
a minimal overhead to the Pex white
box analysis, support the Code
Contracts runtime writer and
encourage the programmatic models
rather than record/replay tests.
Stubs may be used on any .NET method, including non-virtual/static
methods in sealed types.
There are two standard unit testing approaches in this case:
1) Don't test the platform - if the dependency is on a framework class, you don't write tests where that interaction is verified. This typically means you substitute a dependency at test time, but in your case it likely means you inject the table itself.
2) Wrap the platform - if you need to test something that interacts with the platform, then write a wrapper layer for the relevant components
There's also integration and acceptance testing to consider. For both of these cases you would usually simply accept the dependency as it exists in your application.
What precisely are you concerned about testing that you need to directly mock/substitute this class?
Edit:
It seems as if you're looking to avoid rewriting code to be more testable. This is where TypeMock excels, and is the reason why some test advocates think TypeMock can lead to problems. It is, however, the right tool for the job if you absolutely refuse to restructure your code for testability.
Edit #2:
Perhaps I'm being overly obsessive about this, but let's consider a more testable pattern:
Organization()
{
HasUser(name)
}
OrganizationDAL
{
Organization LoadOrganization(id)
}
OrganizationServiceFacade
{
IsUserInOrganization(name, orgid)
{
return OrgDAL.LoadOrganization(id).HasUser(name)
}
}
Organization's natural contains test for a user no longer needs to be platform-dependent, you should be able to inject the datasource. OrganizationDAL is only responsible for loading organizations rather than returning information about organizations (although there are ways to put queries into this layer if necessary). OrganizationServiceFacade is only responsible for providing composed services, which should both satisfy mockability and avoid the need for extra unit tests (it's an Integration or possibly even an Acceptance target) since it's a wrapper class. Depending on how you construct Organizations, you can inject data without relying on a particular notion of how that data works.
You may want to consider using the Repository pattern, basically it's the "wrap the platform" suggestion from Mike. With it you'll be mocking IRepository rather then the DataContext.
http://blogs.microsoft.co.il/blogs/kim/archive/2008/11/14/testable-data-access-with-the-repository-pattern.aspx

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.

Categories