How to do unit testing for nested "using" statements in C#? - c#

I'm working with big legacy projects.
I've started writing unit tests with xUnit.
Also, I'm using the Moq framework.
I've read a lot of articles here, but have not found a clear answer. I stuck with understanding how can I do mocks for two IDisposable objects inside a tested method? The method I would like to test:
public class SomeService: ISomeService
{
...
public async Task<Settings> GetSettings(UserIdentity user)
{
SettingsDBModel dbModel;
using (DBHelperAsync dbHelper = new DBHelperAsync(user))
{
using (DBHelperReaderAsync reader = await dbHelper.ExecuteReader("Stored procedure Name", new { UserID = user.UserID }))
{
dbModel = await reader.GetResult<SettingsDBModel>();
}
}
var settings = new Settings(dbModel);
return settings;
}
...
}
I want to reader.GetResult() method returns some fake data. Any thought how should be implemented of mocks for DBHelperAsync and DBHelperReaderAsync objects?

The class under test should be refactored to decouple it from the DBHelperAsync implementation concern. Classes should depend on abstractions and not concretions.
An abstract explicit dependency should be injected and configured accordingly for run time code. The would now allow the class under test to be flexible enough to be easily tested in isolation. (Explicit Dependency Principle).
If the legacy classes are unable to be modified then they should be wrapped in abstraction that can be modified and then injected into the classes under test.
The provided code above needs a IDBHelperAsyncFactory abstraction that would be injected into the class and used to create the disposable DBHelperAsync which should have also been derived from a disposable abstraction interface IDBHelperAsync : IDisposable.
That would allow those abstractions to be easily mocked/stubbed while testing.

Related

Unit testing for method using database bounded when application started

I use NUnit for my unit-testing. In my current project, I have a problem in which almost all of the functions I want to test are connected to the database. Meanwhile, the database is bounded when the application is started.
I am so confused now, I have read regarding mock unit-testing, but don't know exactly how to handle this problem. Any solution for me here?
To make things harder, this database is static, not as parameter of my method... This makes me so confused
You might want to review the architecture of your application. Make sure the database layer is loosely coupled, for example by using interfaces. This will make it possible to write stubs or mocks for your database layer.
The normal solution to this is to keep your data layer in a separate class that implements a well-known interface. For instance:
public interface IDataLayer
{
IEnumerable<Customer> GetAllCustomers();
Order GetOrderById(int id);
}
You will implement the interface as normal for your actual data access
public class SqlServerDataLayer : IDataLayer
{
// implementation
}
But in your tests, you can now use a mocking framework like Moq or RhinoMocks to set up a mock data layer that returns test data. This ensures you are only testing how your classes use the data, which is ideal.
[Test]
public void TestGettingCustomersRefreshesViewModel()
{
//arrange
var mockDb = new Mock<IDataLayer>();
mockDb.Setup(db => db.GetAllCustomers()).Returns(new List<Customer>());
underTest.DataRepository = mockDb.Object;
//act
underTest.GetCustomerCommand.Execute();
//assert
Assert.That(underTest.CustomerList != null);
}

How to enable unit testing on a tightly coupled business\data layers without DI?

I'm working on a project that is an older 3 tier design, any new functionality added needs to be unit testable.
The problem is the business layer / data layers are tightly coupled like in the sample below. The BL just news up a data layer object... so it's almost impossible to mock up this way. We don't have any Dependency Injection implemented so constructor injection isn't possible. So what is the best way to modify the structure so that the data layer can be mocked up without the use of DI?
public class BLLayer()
{
public GetBLObject(string params)
{
using(DLayer dl = new DLayer())
{
DataSet ds = dl.GetData(params);
BL logic here....
}
}
}
You're not ruling out constructor injection per se, you just don't have an IOC container set up. That's fine, you don't need one. You can do Poor Man's Dependency Injection and still keep constructor injection.
Wrap the DataLayer with an interface, and then create a factory that will make IDataLayer objects on command. Add this as a field to the object you're trying to inject into, replacing all new with calls to the factory. Now you can inject your fakes for testing, like this:
interface IDataLayer { ... }
interface IDataLayerFactory
{
IDataLayer Create();
}
public class BLLayer()
{
private IDataLayerFactory _factory;
// present a default constructor for your average consumer
ctor() : this(new RealFactoryImpl()) {}
// but also expose an injectable constructor for tests
ctor(IDataLayerFactory factory)
{
_factory = factory;
}
public GetBLObject(string params)
{
using(DLayer dl = _factory.Create()) // replace the "new"
{
//BL logic here....
}
}
}
Don't forget to have a default value of the actual factory you want to use in real code.
Dependency Injection is just one of many patterns that fall under the umbrella concept known as "Inversion of Control". The main criteria is to provide a "seam" between components so that you can separate In short, there's more than one way to skin a cat.
Dependency Injection itself has several derivates: Constructor Injection (dependencies passed in through the constructor), Property Injection (dependencies represented as read/write properties) and Method Injection (dependencies are passed into the method). These patterns assume that class is "closed for modification" and expose their dependencies for consumers to change. Legacy code is rarely designed this way, and system-wide architectural changes (such as moving to constructor injection and a IoC container) isn't always straight forward.
Other patterns involve decoupling the resolution and/or construction of objects away from the subject under a test. Simple Gang of Four patterns like a Factory can do wonders. A Service Locator is like a global object factory, and while I'm not a huge fan of this pattern, it can be used to decouple dependencies.
In the example that you've outlined above, the test pattern "Subclass to Test" would allow you to introduce seams without system wide re-architecture. In the pattern, you move object creation calls like "new DLayer()" to a virtual method, and then create a subclass of the subject.
Micheal Feather's "Working with Legacy Code" has a catalog of patterns and techniques that you can use to put your legacy code into a state that would allow you to move towards DI.
If DLayer is only used in the GetBLObject method I would inject a factory in the method call. Something like: (Building on #PaulPhillips example)
public GetBLObject(string params, IDataLayerFactory dataLayerFactory)
{
using(DLayer dl = dataLayerFactory.Create()) // replace the "new"
{
//BL logic here....
}
}
However it seems that what you really want to work with in the Business Layer is a DataSet. So another way is to let GetBLObject take the DataSet in the method call in stead of string param. In order to make that work you could create a class that handles just getting the DataSet from a DLayer. For instance:
public class CallingBusinesslayerCode
{
public void CallingBusinessLayer()
{
// It doesn't show from your code what is returned
// so here I assume that it is void.
new BLLayer().GetBLObject(new BreakingDLayerDependency().GetData("param"));
}
}
public class BreakingDLayerDependency
{
public DataSet GetData(string param)
{
using (DLayer dl = new DLayer()) //you can of course still do ctor injection here in stead of the new DLayer()
{
return dl.GetData(param);
}
}
}
public class BLLayer
{
public void GetBLObject(DataSet ds)
{
// Business Logic using ds here.
}
}
One warning: Mocking out DataSet (which you have to in both this and Paul Phillips solution) can be really cumbersome, so testing this will be possible, but not necessarily a lot of fun.

How does Inversion of Control help me?

I'm trying to understand Inversion of Control and how it helps me with my unit testing. I've read several online explanations of IOC and what it does, but I'm just not quite understanding it.
I developed a sample project, which included using StructureMap for unit testing. StructureMap setup code like the following:
private readonly IAccountRepository _accountRepository
public Logon()
{
_accountRepository = ObjectFactory.GetInstance<IAccountRepository>();
}
The thing I'm not understanding though, is as I see it, I could simply declare the above as the following:
AccountRepository _accountRepository = new AccountRepository();
And it would do the same thing as the prior code. So, I was just wondering if someone can help explain to me in a simple way, what the benefit of using IOC is (especially when dealing with unit testing).
Thanks
Inversion of Control is the concept of letting a framework call back into user code. It's a very abstract concept but in essence describes the difference between a library and a framework. IoC can be seen as the "defining characteristic of a framework." We, as program developers, call into libraries, but frameworks instead call into our code; the framework is in control, which is why we say the control is inverted. Any framework supplies hooks that allow us to plug in our code.
Inversion of Control is a pattern that can only be applied by framework developers, or perhaps when you're an application developer interacting with framework code. IoC does not apply when working with application code exclusively, though.
The act of depending on abstractions instead of implementations is called Dependency Inversion, and Dependency Inversion can be practiced by both application and framework developers. What you refer to as IoC is actually Dependency Inversion, and as Krzysztof already commented: what you're doing is not IoC. I'll discuss Dependency Inversion for the remainder of my answer.
There are basically two forms of Dependency Inversion:
Service Locator
Dependency Injection.
Let's start with the Service Locator pattern.
The Service Locator pattern
A Service Locator supplies application components outside the [startup path of your application] with access to an unbounded set of dependencies. As its most implemented, the Service Locator is a Static Factory that can be configured with concrete services before the first consumer begins to use it. (But you’ll equally also find abstract Service Locators.) [source]
Here's an example of a static Service Locator:
public class Service
{
public void SomeOperation()
{
IDependency dependency =
ServiceLocator.GetInstance<IDependency>();
dependency.Execute();
}
}
This example should look familiar to you, because this what you're doing in your Logon method: You are using the Service Locator pattern.
We say that a Service Locator supplies access to an unbounded set of dependencies, because the caller can pass in any type it wishes at runtime. This is opposite to the Dependency Injection pattern.
The Dependency Injection pattern
With the Dependency Injection pattern (DI), you statically declaring a class's required dependencies; typically, by defining them in the constructor. The dependencies are made part of the class's signature. The class itself isn't responsible for getting its dependencies; that responsibility is moved up up the call stack. When refactoring the previous Service class with DI, it would likely become the following:
public class Service
{
private readonly IDependency dependency;
public Service(IDependency dependency)
{
this.dependency = dependency;
}
public void SomeOperation()
{
this.dependency.Execute();
}
}
Comparing both patterns
Both patterns are Dependency Inversion, since in both cases the Service class isn't responsible of creating the dependencies and doesn't know which implementation it is using. It just talks to an abstraction. Both patterns give you flexibility over the implementations a class is using and thus allow you to write more flexible software.
There are, however, many problems with the Service Locator pattern, and that's why it is considered an anti-pattern. You are already experiencing these problems, as you are wondering how Service Locator in your case helps you with unit testing.
The answer is that the Service Locator pattern does not help with unit testing. On the contrary: it makes unit testing harder compared to DI. By letting the class call the ObjectFactory (which is your Service Locator), you create a hard dependency between the two. Replacing IAccountRepository for testing, also means that your unit test must make use of the ObjectFactory. This makes your unit tests harder to read. But more importantly, since the ObjectFactory is a static instance, all unit tests make use of that same instance, which makes it hard to run tests in isolation and swap implementations on a per-test basis.
I used to use a static Service Locator pattern in the past, and the way I dealt with this was by registering dependencies in a Service Locator that I could change on a thread-by-thread basis (using [ThreadStatic] field under the covers). This allowed me to run my tests in parallel (what MSTest does by default) while keeping tests isolated. The problem with this, unfortunately, was that it got complicated really fast, it cluttered the tests with all kind of technical stuff, and it made me spent a lot of time solving these technical problems, while I could have been writing more tests instead.
But even if you use a hybrid solution where you inject an abstract IObjectFactory (an abstract Service Locator) into the constructor of Logon, testing is still more difficult compared to DI because of the implicit relationship between Logon and its dependencies; a test can't immediately see what dependencies are required. On top of that, besides supplying the required dependencies, each test must now supply a correctly configured ObjectFactory to the class.
Conclusion
The real solution to the problems that Service Locator causes is DI. Once you statically declare a class's dependencies in the constructor and inject them from the outside, all those issues are gone. Not only does this make it very clear what dependencies a class needs (no hidden dependencies), but every unit test is itself responsible for injecting the dependencies it needs. This makes writing tests much easier and prevents you from ever having to configure a DI Container in your unit tests.
The idea behind this is to enable you to swap out the default account repository implementation for a more unit testable version. In your unit tests you can now instantiate a version that doesn't make a database call, but instead returns back fixed data. This way you can focus on testing the logic in your methods and free yourself of the dependency to the database.
This is better on many levels:
1) Your tests are more stable since you no longer have to worry about tests failing due to data changes in the database
2) Your tests will run faster since you don't call out to an external data source
3) You can more easily simulate all your test conditions since your mocked repository can return any type of data needed to test any condition
The key to answer your question is testability and if you want to manage the lifetime of the injected objects or if you are going to let the IoC container do it for you.
Let's say for example that you are writing a class that uses your repository and you want to test it.
If you do something like the following:
public class MyClass
{
public MyEntity GetEntityBy(long id)
{
AccountRepository _accountRepository = new AccountRepository();
return _accountRepository.GetEntityFromDatabaseBy(id);
}
}
When you try to test this method you will find that there are a lot of complications:
1. There must be a database already set up.
2. Your database needs to have the table that has the entity you're looking for.
3. The id that you are using for your test must exist, if you delete it for whatever reason then your automated test is now broken.
If instead you have something like the following:
public interface IAccountRepository
{
AccountEntity GetAccountFromDatabase(long id);
}
public class AccountRepository : IAccountRepository
{
public AccountEntity GetAccountFromDatabase(long id)
{
//... some DB implementation here
}
}
public class MyClass
{
private readonly IAccountRepository _accountRepository;
public MyClass(IAccountRepository accountRepository)
{
_accountRepository = accountRepository;
}
public AccountEntity GetAccountEntityBy(long id)
{
return _accountRepository.GetAccountFromDatabase(id)
}
}
Now that you have that you can test the MyClass class in isolation without the need for a database to be in place.
How is this beneficial? For example you could do something like this (assuming you are using Visual Studio, but the same principles apply to NUnit for example):
[TestClass]
public class MyClassTests
{
[TestMethod]
public void ShouldCallAccountRepositoryToGetAccount()
{
FakeRepository fakeRepository = new FakeRepository();
MyClass myClass = new MyClass(fakeRepository);
long anyId = 1234;
Account account = myClass.GetAccountEntityBy(anyId);
Assert.IsTrue(fakeRepository.GetAccountFromDatabaseWasCalled);
Assert.IsNotNull(account);
}
}
public class FakeRepository : IAccountRepository
{
public bool GetAccountFromDatabaseWasCalled { get; private set; }
public Account GetAccountFromDatabase(long id)
{
GetAccountFromDatabaseWasCalled = true;
return new Account();
}
}
So, as you can see you are able, very confidently, to test that the MyClass class uses an IAccountRepository instance to get an Account entity from a database without the need to have a database in place.
There are a million things you can still do here to improve the example. You could use a Mocking framework like Rhino Mocks or Moq to create your fake objects instead of coding them yourself like I did in the example.
By doing this the MyClass class is completely independent of the AccountRepository so that's when the loosley coupled concept comes into play and your application is testable and more maintainable.
With this example you can see the benefits of IoC in itself. Now if you DO NOT use an IoC container you do have to instantiate all the dependencies and inject them appropriately in a Composition Root or configure an IoC container so it can do it for you.
Regards.

Mocking Enterprise Lib 5 'Database'

Is it possible to mock the enterprise library 5 version of 'Database'? If so... how?
There is no IDatabase interface (which is a mystery as I though Microsoft P&P would be more on the ball about testability benefits of exposing such an interface).
I have a Repository class which used EntLib 5 Data Access Application Block.
I am retro fitting unit tests into this class and need to mock out the dependency on the Database object. This class is now passed the Database via its constructor and uses a Database object to perform operations on the Db.
I use the following to resolve an instance of the Database to be passed to my Repository:
Container.RegisterType<IFooRepository, FooRepository>(
new InjectionConstructor(
EnterpriseLibraryContainer.Current.GetInstance<Database>("FooDbConnStr")
)
);
I don't wish these unit tests to become integration tests.
I have tried using Moq to create a dynamic mock of the Database type, but this has proved tricky as Database requires a connection string and a DbProviderFactory in its constructor. Maybe if there was such a thing as a MockDbProviderFactory.
This is the form that the unit test is taking:
Aside: I also find the use of a static logger class very difficult to test. Hopefully I am missing some trick here, but I must say I am disappointed with testability thus far.
FWIW, I was able to mock a SqlDatabase using Moq. SqlDatabase has a SqlClientPermission attribute which does not play well with Castle Windsor (used by Moq). I had to explicitly instruct Castle to ignore the SqlClientPermission attribute to get the test to work (see line 1 in the example below). Below is a sample unit test (borrowing Steven H's example).
[TestMethod]
public void FooRepo_CallsCorrectSPOnDatabase()
{
Castle.DynamicProxy.Generators.AttributesToAvoidReplicating.Add(typeof(System.Data.SqlClient.SqlClientPermissionAttribute));
var mockSqlDb = new Mock<SqlDatabase>("fake connection string");
mockSqlDb.Setup(s => s.GetStoredProcCommand("sp_GetFoosById"));
var sut = new FooRepository(mockSqlDb);
sut.LoadFoosById(1);
mockSqlDb.Verify(s => s.GetStoredProcCommand("sp_GetFoosById"), Times.Once(), "Stored Procedure sp_GetFoosById was not invoked.");
}
I used FakeItEasy http://code.google.com/p/fakeiteasy/.
I created a mock of SqlDatabase (inherits from Database with a friendlier constructor) passed it to the FooRepostory, called the function under test and asserted expected calls that were made to the Database.
[Test]
public void FooRepo_CallsCorrectSPOnDatabase()
{
var mockDb = A.Fake<SqlDatabase>(x => x.WithArgumentsForConstructor(new object[] { "fakeconnStr" }));
var sut = new FooRepository(mockDb);
sut.LoadFoosById(1);
A.CallTo(() => mockDb.GetStoredProcCommand(Db.SProcs.GetFoosById)).MustHaveHappened(Repeated.Once);
}
Database is an abstract base class, and DbProviderFactory is also abstract, so you can mock them both out. As long as you mock out the operations that you're calling on the Database type (just about everything there is virtual so you should be ok there) you don't actually need to do anything in the provider factory. And the connection string can just be empty or null or whatever.
I personally loaded up the source code and used ReSharper to Extract Interface for the Database object. It rebuilt and I used my custom binaries. Wala - An interface! Hint: Interfaces are simple to mock. Why Microsoft P&P group didn't do this, I do not know.

Is this a poor design?

I'm trying my hand at behavior driven development and I'm finding myself second guessing my design as I'm writing it. This is my first greenfield project and it may just be my lack of experience. Anyway, here's a simple spec for the class(s) I'm writing. It's written in NUnit in a BDD style instead of using a dedicated behavior driven framework. This is because the project targets .NET 2.0 and all of the BDD frameworks seem to have embraced .NET 3.5.
[TestFixture]
public class WhenUserAddsAccount
{
private DynamicMock _mockMainView;
private IMainView _mainView;
private DynamicMock _mockAccountService;
private IAccountService _accountService;
private DynamicMock _mockAccount;
private IAccount _account;
[SetUp]
public void Setup()
{
_mockMainView = new DynamicMock(typeof(IMainView));
_mainView = (IMainView) _mockMainView.MockInstance;
_mockAccountService = new DynamicMock(typeof(IAccountService));
_accountService = (IAccountService) _mockAccountService.MockInstance;
_mockAccount = new DynamicMock(typeof(IAccount));
_account = (IAccount)_mockAccount.MockInstance;
}
[Test]
public void ShouldCreateNewAccount()
{
_mockAccountService.ExpectAndReturn("Create", _account);
MainPresenter mainPresenter = new MainPresenter(_mainView, _accountService);
mainPresenter.AddAccount();
_mockAccountService.Verify();
}
}
None of the interfaces used by MainPresenter have any real implementations yet. AccountService will be responsible for creating new accounts. There can be multiple implementations of IAccount defined as separate plugins. At runtime, if there is more than one then the user will be prompted to choose which account type to create. Otherwise AccountService will simply create an account.
One of the things that has me uneasy is how many mocks are required just to write a single spec/test. Is this just a side effect of using BDD or am I going about this thing the wrong way?
[Update]
Here's the current implementation of MainPresenter.AddAccount
public void AddAccount()
{
IAccount account;
if (AccountService.AccountTypes.Count == 1)
{
account = AccountService.Create();
}
_view.Accounts.Add(account);
}
Any tips, suggestions or alternatives welcome.
When doing top to down development it's quite common to find yourself using a lot of mocks. The pieces you need aren't there so naturally you need to mock them. With that said this does feel like an acceptance level test. In my experience BDD or Context/Specification starts to get a bit weird at the unit test level. At the unit test level I'd probably be doing something more along the lines of...
when_adding_an_account
should_use_account_service_to_create_new_account
should_update_screen_with_new_account_details
You may want to reconsider your usage of an interface for IAccount. I personally stick
with keeping interfaces for services over domain entities. But that's more of a personal preference.
A few other small suggestions...
You may want to consider using a Mocking framework such as Rhino Mocks (or Moq) which allow you to avoid using strings for your assertions.
_mockAccountService.Expect(mock => mock.Create())
.Return(_account);
If you are doing BDD style one common pattern I've seen is using chained classes for test setup. In your example...
public class MainPresenterSpec
{
// Protected variables for Mocks
[SetUp]
public void Setup()
{
// Setup Mocks
}
}
[TestFixture]
public class WhenUserAddsAccount : MainPresenterSpec
{
[Test]
public void ShouldCreateNewAccount()
{
}
}
Also I'd recommend changing your code to use a guard clause..
public void AddAccount()
{
if (AccountService.AccountTypes.Count != 1)
{
// Do whatever you want here. throw a message?
return;
}
IAccount account = AccountService.Create();
_view.Accounts.Add(account);
}
The test life support is a lot simpler if you use an auto mocking container such as RhinoAutoMocker (part of StructureMap) . You use the auto mocking container to create the class under test and ask it for the dependencies you need for the test(s). The container might need to inject 20 things in the constructor but if you only need to test one you only have to ask for that one.
using StructureMap.AutoMocking;
namespace Foo.Business.UnitTests
{
public class MainPresenterTests
{
public class When_asked_to_add_an_account
{
private IAccountService _accountService;
private IAccount _account;
private MainPresenter _mainPresenter;
[SetUp]
public void BeforeEachTest()
{
var mocker = new RhinoAutoMocker<MainPresenter>();
_mainPresenter = mocker.ClassUnderTest;
_accountService = mocker.Get<IAccountService>();
_account = MockRepository.GenerateStub<IAccount>();
}
[TearDown]
public void AfterEachTest()
{
_accountService.VerifyAllExpectations();
}
[Test]
public void Should_use_the_AccountService_to_create_an_account()
{
_accountService.Expect(x => x.Create()).Return(_account);
_mainPresenter.AddAccount();
}
}
}
}
Structurally I prefer to use underscores between words instead of RunningThemAllTogether as I find it easier to scan. I also create an outer class named for the class under test and multiple inner classes named for the method under test. The test methods then allow you to specify the behaviors of the method under test. When run in NUnit this gives you a context like:
Foo.Business.UnitTests.MainPresenterTest
When_asked_to_add_an_account
Should_use_the_AccountService_to_create_an_account
Should_add_the_Account_to_the_View
That seems like the correct number of mocks for a presenter with a service which is supposed to hand back an account.
This seems more like an acceptance test rather than a unit test, though - perhaps if you reduced your assertion complexity you would find a smaller set of concerns being mocked.
Yes, your design is flawed. You are using mocks :)
More seriously, I agree with the previous poster who suggests your design should be layered, so that each layer can be tested separately. I think it is wrong in principle that testing code should alter the actual production code -- unless this can be done automatically and transparently the way code can be compiled for debug or release.
It's like the Heisenberg uncertainty principle - once you have the mocks in there, your code is so altered it becomes a maintenance headache and the mocks themselves have the potential to introduce or mask bugs.
If you have clean interfaces, I have no quarrel with implementing a simple interface that simulates (or mocks) an unimplemented interface to another module. This simulation could be used in the same way mocking is, for unit testing etc.
You might want to use MockContainers in order to get rid of all the mock management, while creating the presenter. It simplifies unit tests a lot.
This is okay, but I would expect an IoC automocking container in there somewhere. The code hints at the test writer manually (explicitly) switching between mocked and real objects in tests which should not be the case because if we are talking about a unit test (with unit being just one class), it's simpler to just auto-mock all other classes and use the mocks.
What I'm trying to say is that if you have a test class that uses both mainView and mockMainView, you don't have a unit test in the strict sense of the word -- more like an integration test.
It is my opinion that if you find yourself needing mocks, your design is incorrect.
Components should be layered. You build and test components A in isolation. Then you build and test B+A. Once happy, you build layer C and test C+B+A.
In your case you shouldn't need a "_mockAccountService". If your real AccountService has been tested, then just use it. That way you know any bugs are in MainPresentor and not in the mock itself.
If your real AccountService hasn't been tested, stop. Go back and do what you need to ensure it is working correctly. Get it to the point where you can really depend on it, then you won't need the mock.

Categories

Resources