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);
}
Related
I don't have a lot of experience with unit testing. For example I have simple method in the application:
public void GetName()
{
UserRights rights = new UserRights(new DatabaseContext());
string test = rights.LookupNameByID("12345");
Console.WriteLine(test);
}
In this case I'm able to test all methods of UserRights class by passing mocked DatabaseContext, but how can I test GetName() method? What is the best practice? Where DatabaseContext should be created?
If you want to test the GetName method in a properly isolated way (i.e. a Unit Test) then you can't use new to create the UserRights instance in the method itself; because a test is really just another client of the code, therefore it can't (and shouldn't) know anything about how GetName works internally
So what this means is that for a proper Unit Test you must be able to replace all dependencies of a method with ones that the client fully controls - in the case, the code in the Unit Test is the client.
In your posted code, the client code has no control at all over UserRights nor DatabaseContext, so this is the first thing that has to change.
You need to rework your code so that the UserRights implementation can be supplied by the client. In fact once that's done, the problem about where DatabaseContext comes from is actually irrelevant for the Unit test because it doesn't care about how UserRights itself performs its tasks!
There are a number of ways of doing this; you can use Mocks or Stubs, you can use Constructor or Method injection, you could use a UserRights factory. Here is an example of using very simple stubs which IMHO is the best way to start and avoids having to learn a Mocking framework -- I personally would use Mocks for this but that's cos I am lazy :)
(code below assumes the class containing GetName is called "UserService", and uses xUnit framework; but MSTest will work just fine too)
Let's suppose you have control over the code of UserService so you can make the LookupNameByID method virtual (if you can't, then you may have to go the route if interfaces and mocks)
public class UserRights
{
public virtual LookupNameByID(string id)
{
//does whatever a UserRights does.
}
}
public class UserService
{
readonly UserRights _rights;
public UserService(UserRights rights)
{
_rights=rights; //null guard omitted for brevity
}
public string GetName(string id)
{
return _rights.LookupNameByID(id);
}
}
now in your unit test code suppose you create a sub-class of UserRights like this:
public class ExplodingUserRights: UserRights
{
public override string LookupNameByID(string id)
{
throw new Exception("BOOM!");
}
}
Now you can write a test to see how GetName reacts when something bad happens:
[Fact]
public void LookupNameByID_WhenUserRightsThrowsException_DoesNotReThrow()
{
//this test will fail if an exception is thrown, thus proving that GetName doesn't handle exceptions correctly.
var sut = new UserService(new ExplodingUserRights()); <-Look, no DatabaseContext!
sut.GetName("12345");
}
and one for when good things happen:
public class HappyUserRights: UserRights
{
public override string LookupNameByID(string id)
{
return "yay!";
}
}
[Fact]
public void LookupNameByID_ReturnsResultOfUserRightsCall()
{
//this test will fail if an exception is thrown, thus proving that GetName doesn't handle exceptions correctly.
var sut = new UserService(new HappyUserRights());
var actual = sut.GetName("12345");
Assert.Equal("yay!",actual);
}
and so on. Note that we never went anywhere near DatabaseContext, because that's a problem you only have to solve when you unit test the UserRights class itself. (and at that point I would probably recommend using Jeroen's advice from his linked article,and do an integration test, unless setup of a database for each test is something you can't or won't do, in which case you need to use interfaces and mocks)
Hope that helps.
Separating your codes reliance on DB Context is something you will want to investigate, this can be accomplished using the Repository pattern. Since you're passing the DB Context into your objects constructor, in this case UserRights, you can pretty easily change your code to take in an Interface (or simply add an overloaded contructor to the class that accepts an interface, then call that in your unit tests, preserving any existing code). There are lots of ways to get this done, a quick Google search yielded the following article:
http://romiller.com/2012/02/14/testing-with-a-fake-dbcontext/
http://www.codeproject.com/Articles/207820/The-Repository-Pattern-with-EF-code-first-Dependen
Once your class can accept an interface rather than (or as an alternative to) the strongly typed DB Context object you can use a Mock framework to assist with testing. Take a look at Moq for examples on how to use these in your unit tests https://github.com/Moq/moq4/wiki/Quickstart
Be Aware: Moq can become difficult to work with when your tests require data that is related via foreign keys, the syntax can be complicated to get your head around. One thing to watch out for is the temptation to make changes to your code just to make a unit test easier to set up, while there may be value in making this change it also may indicate that you need to re-think your unit test rather than violate your applications architecture and/or design patterns
This question already has answers here:
What are the differences between mocks and stubs on Rhino Mocks?
(5 answers)
Closed 9 years ago.
I have lately become very interested in testing and Im now trying to learn to do unit testing in the best way possible. I use NUnit together with Rhino Mocks. I have also been reading a lot over here at Stackoverflow but havent been able to find a clear answer to my question.
What I wonder is if I have a method like the below, should I mock the OfficeClass dependency and also test GetAllOffices or only use a stub for the dependency and verify that the method GetAllOffices has been called and that I indeed get the offices back that I expected from my setup for the stub?
public Offices GetAllOffices()
{
try
{
var offices = officeClass.GetAllOffices();
return offices;
}
}
Will it make any difference if the OfficeClass is just another POCO or if it is let say a web service in sence of mocking vs stubbing?
Long question short: When to Mock and when to Stub in unit testing?
Mocks use a framework to generate a "mock" of your dependency. For example if officeClass is a repository for your data then you can use a mock framework (I use MOQ) to generate a mock of your repository. That's why using interfaces for your dependency make it ideal for testing, the mocking framework can easily make a mock of an interface for testing.
With stubs as I understand it, you manually stub out your dependency and create canned responses. For example if you have an interface IOfficeClass and you create a new class that inherits from it, you can inject that class into your service to allow you to use it.
Again things like web services should be wrapped in some interface (like the IRepository pattern), that will allow you to easily test your logic without needing to hit the web service. The same with POCO classes.
So for example in your case you would have:
public interface IOfficeRepository
{
IQueryable<Office> GetAll();
}
And for your service
public class MyOfficeService
{
private readonly IOfficeRepository officeRepostiory;
public MyOfficeService(IOfficeRepository repository)
{
this.officeRepostiory = repository;
}
public Office GetOffice(int id)
{
return this.officeRepostiory.GetAll().SingleOrDefault(o => o.Id == id);
}
}
This way you can also change your underlying datasource without having to modify your main application or business logic code.
Your unit test would look something like this using moq:
[TestClass]
public class OfficeUnitTest
{
private MyOfficeService service;
[TestInitialize]
public void Setup()
{
var officeRepository = new Mock<IOfficeRepository>();
var office = new List<Office>();
office.Add(new Office{ Id = 1 });
officeRepository.Setup(m => m.GetAll()).Returns(office.AsQueryable());
this.service = new MyOfficeService(officeRepository.Object);
}
[TestMethod]
public void TestGetById()
{
Assert.IsNotNull(service.GetOffice(1));
// my mock will never return a value for 2
Assert.IsNull(service.GetOffice(2));
}
}
You can read more about mocks and stubs below:
http://martinfowler.com/articles/mocksArentStubs.html
http://msdn.microsoft.com/en-us/library/ff649690.aspx
I have a Lin2Sql DataContext that I am using to get all my data from a sql database however I am struggling to find a way to successfully Mock this so that I can create relevant Unit Tests.
In my data access objects that I am wanting to test I am refreshing the context each time and I am finding it difficult to find a simple suitable way to mock this.
Any help with this matter will be greatly appreciated.
Mocking the linq-to-sql context is indeed a huge task. I usually work around it by letting my unit tests run against a separate database copy, with data specially crafted to fit the unit tests. (I know it can be argued that it's no longer unit tests, but rather integration tests, but I don't care as long as I get the code tested).
To keep the database in a known state I wrap each test in a TransactionScope which is rolled back at the end of the test. That way the state of the database is never changed.
A sample test method looks like this:
[TestMethod]
public void TestRetire()
{
using (TransactionScope transaction = new TransactionScope())
{
Assert.IsTrue(Car.Retire("VLV100"));
Assert.IsFalse(Car.Retire("VLV100"));
// Deliberately not commiting transaction.
}
}
The code is from a blog post about the method I wrote some time ago: http://coding.abel.nu/2011/12/using-transactions-for-unit-tests/
Since you request a way to mock a DataContext I assume that you really want to do some unit tests and not integration tests.
Well, I will tell you how to accomplish this, but first I would like to encourage you to read the following links, they are all about writing clean testable code.
http://misko.hevery.com/code-reviewers-guide/
http://misko.hevery.com/attachments/Guide-Writing%20Testable%20Code.pdf
And check the links from this response:
https://stackoverflow.com/a/10359288/1268570
Watch the clean code talks from Misko Hevery (given to the Google people)
http://www.youtube.com/watch?v=wEhu57pih5w&feature=player_embedded
http://www.youtube.com/watch?v=RlfLCWKxHJ0&feature=player_embedded
http://www.youtube.com/watch?v=-FRm3VPhseI&feature=player_embedded
http://www.youtube.com/watch?v=4F72VULWFvc&feature=player_embedded
One thing that I used to repeat to myself and to my fellows at work, is that anyone can write a unit test, because they are silly easy to write. So a simple test is essentially all about making some comparisons and throw exceptions if the results fails, anyone can do that. Of course, there are hundreds of frameworks to help us write those tests in an elegant way. But the real deal, and the real effort shroud be put on learn how to write clean testable code
Even if you hire Misko Hevery to help you write tests, he will have a real hard time writing them if your code is not test-friendly.
Now the way to mock a DataContext objects is: do not do it
Instead wrap the calls using a custom interface instead:
public interface IMyDataContextCalls
{
void Save();
IEnumerable<Product> GetOrders();
}
// this will be your DataContext wrapper
// this wll act as your domain repository
public class MyDataContextCalls : IMyDataContextCalls
{
public MyDataContextCalls(DataClasses1DataContext context)
{
this.Context = context;
}
public void Save()
{
this.Context.SubmitChanges();
}
public IEnumerable<Product> GetOrders()
{
// place here your query logic
return this.Context.Products.AsEnumerable();
}
private DataClasses1DataContext Context { get; set; }
}
// this will be your domain object
// this object will call your repository wrapping the DataContext
public class MyCommand
{
private IMyDataContextCalls myDataContext;
public MyCommand(IMyDataContextCalls myDataContext)
{
this.myDataContext = myDataContext;
}
public bool myDomainRule = true;
// assume this will be the SUT (Subject Under Test)
public void Save()
{
// some business logic
// this logic will be tested
if (this.myDomainRule == true)
{
this.myDataContext.Save();
}
else
{
// handle your domain validation errors
throw new InvalidOperationException();
}
}
}
[TestClass]
public class MyTestClass
{
[TestMethod]
public void MyTestMethod()
{
// in this test your mission is to test the logic inside the
// MyCommand.Save method
// create the mock, you could use a framework to auto mock it
// or create one manually
// manual example:
var m = new MyCommand(new MyFakeDataContextFake());
m.Invoking(x => x.Save())
//add here more asserts, maybe asserting that the internal
// state of your domain object was changed
// your focus is to test the logic of the domain object
.ShouldNotThrow();
//auto mock example:
var fix = new Fixture().Customize(new AutoMoqCustomization());
var sut = fix.CreateAnonymous<MyCommand>();
sut.myDomainRule = false;
sut.Invoking(x => x.Save())
.ShouldThrow<InvalidOperationException>();
}
public class MyFakeDataContextFake : IMyDataContextCalls
{
public void Save()
{
// do nothing, since you do not care in the logic of this method,
// remember your goal is to test the domain object logic
}
public IEnumerable<Product> GetOrders()
{
// we do not care on this right now because we are testing only the save method
throw new NotImplementedException();
}
}
}
Notes:
When you declare your IMyDataContextCalls interface you are actually abstracting the use of a DataContext, therefore this interface should contain only POCO objects (most of the time), if you follow this approach your interfaces will be decoupled from any undesired dependency.
In the specific MyDataContextCalls implementation, you are explicitly using a DataClasses1DataContext context, but you are free to change the implementation at any time and that won't affect your external code, and that's because you are always working with the IMyDataContextCalls interface instead. So at any time you could change for example this implementation for another one using the wonderful NHibernate =) or the poor ef or a mock one
At last, but not least. please double check my code, and you will notice that there are no new operators in the domain objects. This is a rule of dumb when writing test friendly code: decouple the responsibility of creating objects outside of your domain objects
I personally use three frameworks on every project and on every test I write, I really recommend them:
AutoFixture
Moq
FluentAssertions
For example, in the code above, I showed you how to write a manual fake for your repository, but that clearly is something we do not want to do in a real project, imagine the number of objects you would have to code in order to write your tests.
Instead use the power of AutoFixture combined with Moq:
This line: var m = new MyCommand(new MyFakeDataContextFake());
Will become:
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var sut = fixture.CreateAnonymous<MyCommand>();
And that's it, this code will automatically create mocks for all the objects needed in the constructor of MyCommand.
In short, you don't mock DataContext. You extract interface from it and mock that interface using some collections for entity sets, and then verify contents of those collections.
I'm trying to wrap my head around unit testing, and I've encountered a behavior that I'm unsure of:
"Can Backup Inventory"
Basically, the "Inventory" table is copied to the "InventoryHistory" table, and given a time-stamp of when the backup occurred ("HistoryDate").
Here's the code for backing-up inventory:
DateTime historyDate = DateTime.Now;
MyDataContext db = new MyDataContext();
db.GetTable<InventoryHistory>().InsertAllOnSubmit(
db.GetTable<Inventory>()
.Select(i => new InventoryHistory
{
ID = i.ID,
ItemName = i.ItemName,
/* etc, etc, etc */
HistoryDate = historyDate
})
);
My questions are:
Should/Can this behavior be broken down into smaller unit-testable parts?
Since I am testing against a dedicated test database, should I be using a mocking tool and following the abstract factory pattern for any "repositories"?
The question I would ask is that is this really a unit test? A unit test would consider mocked Table<TEntity> instances, because we're not concerned with the actual data, rather that the mechanism of creating the items is correct.
In your snippet above, it seems that you are unit testing the Linq methods themselves, not any specific code you have written yourself.
As for your last question, one of the fundamental mistakes made with mocking is the assumption of what to test when mocking. Typically you would be mocking a something consumed by the type you want to test. E.g.:
public ICalculatorService
{
int Add(int a, int b);
}
[Test]
public void CannAdd()
{
var mock = Mock<ICalculatorService();
mock.Setup(m => m.Add(It.IsAny<int>(), It.IsAny<int>()))
.Returns(100);
var service = mock.Object;
Assert(service.Add(1, 2) == 100); // Incorrect
}
The above is a pointless test, because I am testing that it is returning exactly what I have told it to. I'm not testing the Moq framework here, I need to test my code, so I would need to be testing the consumer:
public class Calculator
{
private readonly ICalculatorService _service;
public Calculator(ICalculatorService service)
{
_service = service;
}
public int Add(int a, int b)
{
return _service.Add(a, b);
}
}
[Test]
public void CannAdd()
{
var mock = Mock<ICalculatorService();
mock.Setup(m => m.Add(It.IsAny<int>(), It.IsAny<int>()))
.Returns(100);
var calculator = new Calculator(mock.Object);
Assert(calculator.Add(1, 2) == 100); // Correct
}
That's more like it (although a simplistic example). I am now testing the Calculator consumer itself, not the consumable. In your example, even if you were mocking your DataContext to return dummy instances of Table<TEntity>, what real benefits do you get?
Realistically you'd probably create a repository, e.g. an IInventoryRepository, and create a consumer of that repository (could be a domain model, a controller, etc). Then through testing, you'd mock that repository, and test your consumer.
This looks like a fairly atomic operation to me, not much opportunity for breaking it apart.
Unit testing does not hit the database- that's integration testing. If you want a good unit test for this, you would test for behavior- in this case, that the history is backed up when it's supposed to be.
By way of full disclosure, I'm only just starting to learn EF and LINQ and the best way to test them, so you may get some more useful information regarding them in particular, so these are just general testing answers.
1.
I can't see a way that this can be further broken down to be isolated for unit testing, apart from:
ID = i.ID,
ItemName = i.ItemName,
/* etc, etc, etc */
HistoryDate = historyDate
being refactored into a seperate method to be unit tested as the only other code are LINQ calls, which MS are responsible for testing.
2.
I don't think you'd be able to introduce a seam to isolate it with the abstract repository factory pattern, since you're calling into a datacontext.
I'm not sure whether you should fake this (and since you'd be testing against it will be a mock proper - a fake that you test against, a fake that you don't test against is a stub) but since it's calling into a test server, you can make it an automated integration test since the functionality involves the interaction with the data store.
At first, method you describe looks simply and I'm not sure it needs any unit tests.
But, if you want to decompose it, you may do this:
Extract method for getting list of inventories for backup
IQueryable GetInventoryForBackup(this DataContext context)
{
return context.GetTable();
}
Extract method to convert Inventory to InventoryHistory
IEnumerable ToInventoryHistory(this IEnumerable data, DateTime historyDate)
{
return data.Select(i => new InventoryHistroy { ID = i.Id ....
}
Extract method to save sequence of InventoryHistory
void SaveHistory(IEnumerable data)
{
dataContext.InsertAllOnSubmit(data);
dataContext.SubmitChanges();
}
Now you have seemsful methods and you can easy write unit tests for.
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.