Mocking Enterprise Lib 5 'Database' - c#

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.

Related

Are there any ways to mock entity framework calls that create new connections directly within methods

I am new to unit testing and mocking. The project I am working on has many methods that look like this:
public bool MyMethod(int param, int param2)
{
using (SomeEntity dBcontext = new SomeEntity())
{
FancyObj theobj = dBcontext.MyObjs.FirstOrDefault(l => l.ObjId == param2);
if (theobj != null && theobj.CurrentSeason != param) //if season has changed then update
{
theobj .CurrentSeason = param;
dBcontext.SaveChanges();
return true;
}
return false;
}
}
I am using Telerik JustMock and unless I am missing something, there is no way for me to Mock the entity call since its being instantiated directly within the method in test.
Is my only solution to modify the method/class to hold a property of type SomeEntity?
Newing up an instance of required dependency (instead of asking for it in the constructor) kills testability. Essentially, by using new operator, you are mixing the concern of application instantiation with concern of application logic.
Dependency injection to the rescue! Your class under test should ask for all the things required to get its job done in the constructor and rely on interfaces, not the concrete implementations. That way, you will be able to provide fake implementations to make your unit test fully isolated.
Without refactoring your code I think you may be out of luck with conventional mock frameworks, since all Mock Frameworks depend on methods being either virtual or an interface.
But if you own Visual Studio Premium or Ultimate edition you may use Microsoft Fakes which allow you modify/replace/intercept calls to non-virtual methods and properties (works by modifying/injecting CIL code into that 3rd assemblies when they are loaded).
Whilst Dependency injection is probably the better way to go in the long term (it'll typically improve the structure of your code), there are commercial solutions like Typemock that allow you to test code that can't be tested in a conventional way. This is a bit of a mixed blessing, as you can become dependant on the mocking framework and don't necessarily reap the structural changes that can be encouraged by unit testing with more traditional mocking frameworks. However it should allow you to test the situation you're describing.
An example from their website shows how they are able to get a handle to the object created within their Calculate function. As is illustrated in some of their other examples, this handle can then be used to setup expectations on the calls to that dependency:
public static int Calculate(int a, int b)
{
var dependency = new Dependency();
dependency.CheckSecurity("typemock", "rules");
return a + b;
}
[TestMethod,Isolated]
public void FakeConstructor()
{
// Fake the Dependency constructor
var fakeHandle = Isolate.Fake.NextInstance<dependency>();
var result = ClassUnderTest.Calculate(1, 2);
Assert.AreEqual(3, result);
}
There are various different pricing options and I'm not sure what you get for each tier, however if you really don't want to change your code and you have fairly deep pockets it may be worth considering.
Yes, it is possible to arrange the return value of a new expression using the commercial version of JustMock.
var mock = Mock.Create<SomeEntity>();
Mock.Arrange(() => new SomeEntity()).Returns(mock);
From here on you can arrange the mock to have the behavior you need for the test. If you're using EF6, then you can try Telerik.JustMock.EntityFramework that plugs into JustMock to create in-memory mock DB contexts for your tests.

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 use mocks in this case?

Here is my problem:
I have an n-tiers application for which I have to write unit tests. Unit tests are for the business layer.
I have a method to test called Insert() and this one use two protected methods from inheritance and call directly a method from Data access layer.
So I have made a mock object for the DAL. But here is the point, in a (edit :) protected method from inheritance, It will use another object from DAL! It seems it is not possible to mock this one!
Here is the method for test code:
public int Insert(MYOBJECT aMyObject)
{
//first inherited method use the FIRSTDALOBJECT so the mock object --> No problem
aMyObject.SomeField= FirstInherited();
//Second inherited method (see after) --> my problem
aMyObject.SomeOtherField = SecondInherited();
// Direct access to DALMethod, use FIRSTDALOBJECT so the mock -->No Problem
return this.FIRSTDALOBJECT.Insert(aMyObject);
}
Here is the SecondInherited method:
protected string SecondInherited ()
{
// Here is my problem, the mock here seems not be possible for seconddalobject
return ( new SECONDDALOBJECT Sdo().Stuff());
}
And here is the unit test method code :
[TestMethod()]
public void InsertTest()
{
BLLCLASS_Accessor target = new BLLCLASS_Accessor();
MYOBJECT aMyObject = new MYOBJECT { SomeField = null, SomeOtherField = 1 };
int expected = 1;
int actual;
//mock
var Mock = new Mock<DAL.INTERFACES.IFIRSTDALOBJECT>();
//Rec for calls
List<SOMECLASS> retour = new List<SOMECLASS>();
retour.Add(new SOMECLASS());
//Here is the second call (last from method to test)
Mock
.Setup(p => p.Insert(aMyObject))
.Returns(1);
// Here is the first call (from the FirstInherited())
Mock
.Setup(p => p.GetLast())
.Returns(50);
// Replace the real by the mock
target.demande_provider = Mock.Object;
actual = target.Insert(aMyObject);
Assert.AreEqual(/*Some assertion stuff*/);
}
Thank you for reading all the question :-) Hope it is clear enough.
Your text seems to say that SecondInherited is private, while in the code example it is protected. Anyway, if it is not protected, I would suggest changing its access qualifier as the first step.
You can create a subclass solely for testing purposes, and override SecondInherited there to avoid creating SECONDDALOBJECT and just return some value suitable for your tests.
This way you can write your first unit test(s) with minimal changes to the class being tested, thus minimizing the chances of breaking something. Once you have the unit tests in place, these allow you to do more refactoring safely, eventually achieving a better (more testable / mockable) design, such as using Dependency Injection, or a Factory. (I would probably prefer an Abstract Factory over Factory Method here, as the latter would practically force you to keep subclassing the tested class).
The fundamental, highly recommended book for learning this technique (and many more) is Working Effectively With Legacy Code.
No chance to mock this with MOQ.
You have two options:
Use TypeMock or Moles to mock the SECONDDALOBJECT class
Refactor the code, so the instance of SECONDDALOBJECT isn't created in the way it is, but in a way that can be mocked (Factory method, DI, ...) (prefered!)

How to handle setting up complex unit test and have them only test the unit

I have a method that takes 5 parameters. This method is used to take a bunch of gathered information and send it to my server.
I am writing a unit test for this method, but I am hitting a bit of a snag. Several of the parameters are Lists<> of classes that take some doing to setup correctly. I have methods that set them up correctly in other units (production code units). But if I call those then I am kind of breaking the whole idea of a unit test (to only hit one "unit").
So.... what do I do? Do I duplicate the code that sets up these objects in my Test Project (in a helper method) or do I start calling production code to setup these objects?
Here is hypothetical example to try and make this clearer:
File: UserDemographics.cs
class UserDemographics
{
// A bunch of user demographic here
// and values that get set as a user gets added to a group.
}
File: UserGroups.cs
class UserGroups
{
// A bunch of variables that change based on
// the demographics of the users put into them.
public AddUserDemographicsToGroup(UserDemographcis userDemographics)
{}
}
File: UserSetupEvent.cs
class UserSetupEvent
{
// An event to record the registering of a user
// Is highly dependant on UserDemographics and semi dependant on UserGroups
public SetupUserEvent(List<UserDemographics> userDemographics,
List<UserGroup> userGroups)
{}
}
file: Communications.cs
class Communications
{
public SendUserInfoToServer(SendingEvent sendingEvent,
List<UserDemographics> userDemographics,
List<UserGroup> userGroups,
List<UserSetupEvent> userSetupEvents)
{}
}
So the question is: To unit test SendUserInfoToServer should I duplicate SetupUserEvent and AddUserDemographicsToGroup in my test project, or should I just call them to help me setup some "real" parameters?
You need test duplicates.
You're correct that unit tests should not call out to other methods, so you need to "fake" the dependencies. This can be done one of two ways:
Manually written test duplicates
Mocking
Test duplicates allow you to isolate your method under test from its dependencies.
I use Moq for mocking. Your unit test should send in "dummy" parameter values, or statically defined values you can use to test control flow:
public class MyTestObject
{
public List<Thingie> GetTestThingies()
{
yield return new Thingie() {id = 1};
yield return new Thingie() {id = 2};
yield return new Thingie() {id = 3};
}
}
If the method calls out to any other classes/methods, use mocks (aka "fakes"). Mocks are dynamically-generated objects based on virtual methods or interfaces:
Mock<IRepository> repMock = new Mock<IRepository>();
MyPage obj = new MyPage() //let's pretend this is ASP.NET
obj.IRepository = repMock.Object;
repMock.Setup(r => r.FindById(1)).Returns(MyTestObject.GetThingies().First());
var thingie = MyPage.GetThingie(1);
The Mock object above uses the Setup method to return the same result for the call defined in the r => r.FindById(1) lambda. This is called an expecation. This allows you to test only the code in your method, without actually calling out to any dependent classes.
Once you've set up your test this way, you can use Moq's features to confirm that everything happened the way it was supposed to:
//did we get the instance we expected?
Assert.AreEqual(thingie.Id, MyTestObject.GetThingies().First().Id);
//was a method called?
repMock.Verify(r => r.FindById(1));
The Verify method allows you to test whether a method was called. Together, these facilities allow you focus your unit tests on a single method at a time.
Sounds like your units are too tightly coupled (at least from a quick view at your problem). What makes me curious is for instance the fact that your UserGroups takes a UserDemographics and your UserSetupEvent takes a list of UserGroup including a list of UserDemographics (again). Shouldn't the List<UserGroup> already include the ÙserDemographics passed in it's constructor or am I misunderstanding it?
Somehow it seems like a design problem of your class model which in turn makes it difficult to unit test. Difficult setup procedures are a code smell indicating high coupling :)
Bringing in interfaces is what I would prefer. Then you can mock the used classes and you don't have to duplicate code (which violates the Don't Repeat Yourself principle) and you don't have to use the original implementations in the unit tests for the Communications class.
You should use mock objects, basically your unit test should probably just generate some fake data that looks like real data instead of calling into the real code, this way you can isolate the test and have predictable test results.
You can make use of a tool called NBuilder to generate test data. It has a very good fluent interface and is very easy to use. If your tests need to build lists this works even better. You can read more about it here.

How do I Unit Test a function that inserts a record into a RIA Services DB?

This is a sample function that works with an entity, saves it to a db and then causes problems because we can't write a Unit Test for it. Check it out:
// this class exists in a Silverlight Class Library
public class EmployeeSaver
{
....
public void Go()
{
Employee e = new Employee();
e.Name="Jeremiah";
... // Other stuff that really needs to be tested
_DataContext.Employees.Add(e);
_DataContext.SubmitChanges();
}
}
Because the nature of RIA Services, a DomainService doesn't run inside of the Silverlight Unit Testing framework. This means I don't have access to RIA when I do my unit tests.
We've thought about mock databases, but this class actually creates an Entity (Employee) to be added to the DB. This is problematic because Mock Databases don't use this entity but a MockEntity class that looks similar to the original entity.
We're not trying to test RIA itself, but how we use the entities generated by RIA.
My end goal would be to write a function similar to this:
[TestMethod]
public void Test()
{
EmployeeSaver s = new EmployeeSaver();
s.Go();
Assert.IsEqual( DataContext.Employees.Last().Name, "Jeremiah" );
}
How can I test this function? What testing framework should I use? Am I way off for using the Silverlight Testing Framework?
In your unit test, instance s needs to have a stubbed out implementation of _DataContext. When the Go method is called, and it calls:
_DataContext.Employees.Add(e);
_DataContext.SubmitChanges();
it will call into your stub. The stub should then record the fact that an employee got added and changes were submitted.
After the call to Go, you should query the stub to ensure that the new employee got added, and call to SubmitChanges occurred.
As a secondary note:
I don't really agree with the last part of the other answer in that you should not care whether Go calls various methods of _DataContext. It is true that you're not concerned about testing _DataContext methods here, but the unit test for Go needs to ensure that the Go method is calling the _DataContext methods properly. The rationale is that every line of the Go method should be testable. If you didn't do this verification, then you could remove the calls to _DataContext method, breaking the code, but the unit test wouldn't catch it. This would break Bob Martin's the "three rules of TDD" principle.
A hand rolled mock database could store your object as is. We use such a system where the repositories are stored in dictionaries of .
You don't even need to go that far though. You could just use a mock interface for the _DataContext with something like RhinoMocks to make sure that the methods you expect to be called were (its not your concern for this test that _DataContext.SubmitChanges() works (that would be up it it's unit test) you only care that Go set the object and called save.

Categories

Resources