when I applying the unit testing on Insert, Update and Delete operation. At that time the record inserted, updated and deleted in the database as well.
How it possible?
Can anyone give the solution to prevent the database effect?
Thanks,
Ideally you should be using mocking for scenarios where db interaction is there. Make sure you have separate out your db interaction logic and it is interface driven. Then you can create mock objects, wherein you define the expectation of your db interaction interfaces. So for example, if for example InsertSomething() method is called, what should be returned from this method? and so on. Sharing some links on details about unit testing and mocking.
https://msdn.microsoft.com/en-us/library/ff650441.aspx
https://github.com/Moq/moq4
http://www.developerhandbook.com/unit-testing/writing-unit-tests-with-nunit-and-moq/
Testing a MVC Controller fails with NULL reference exception
As another option, you can go for separate real database for testing purpose, if it is essential to execute tests against database. You can also, execute sql script at the start and after running the test to seed and clean data respectively to keep the database pristine
It is possible either by mocking your database (used in unit tests) or creating new database used only for testing purpose (integration tests).
I would recommend using these two approaches together. Remember, that amount of unit tests should be much bigger than integration tests.
Here is simple example how to mock database (using Moq library).
public class HomeController : Controller
{
private IUserRepository _repository;
public HomeController(IUserRepository repository)
{
_repository = repository;
}
public ActionResult AddNewUser(User newUser)
{
_repository.AddUser(newUser);
return View();
}
}
public interface IUserRepository
{
void AddUser(User newUser);
}
public class UserRepository : IUserRepository
{
private DBContext _context;
public UserRepository(DBContext context)
{
_context = context;
}
public void AddUser(User newUser)
{
_context.Users.Add(newUser);
}
}
[Test]
public void ShouldMockRepository()
{
// Given
var repository = new Mock<IUserRepository>();
var controller = new HomeController(repository.Object);
// When
controller.AddNewUser(new User());
// Then
repository.Verify(r => r.AddUser(It.IsAny<User>()), Times.Once);
}
Related
I'm currently writing unit test for my project where I'm using HttpContext.Current.User.Identity.Name at a defined time. Unfortunately, I can't make the test work since HttpContext is null when I run the test.
I already tried some solution I found on internet like Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity("rmllcc"), new string[0]); but I can't get it work.
I'm using a Forms Authenticate system, xUnit with Moq. I'm not testing a controller but a Repository where I'm just logguing each time a user make use of a particular method. How could I accomplish this?
Listen to what your tests are telling you: use the fact that this test is hard to write to think about the structure of your code. You have introduced a dependency in your repository layer to the web application. That's not good. You also have two things going on in your repository: data access and logging.
Maybe wrap the current user in an abstraction that will get the user you need, but can be easily stubbed. Or you could wrap the repository in a decorator that does the logging for you.
Sorry this is not a direct answer to the question but, when tests are hard to write, there is usually a deeper underlying reason that you need to address.
I suggest you dont use the HttpContext from the repository, Make a own context class or a Interface wrapping the user-property.
Something like this:
public class MyContext
{
public MyContext(string username)
{
Username = username;
}
public string Username { get; private set; }
public static MyContext CreateFromHttpContext(HttpContext httpContext){
return new MyContext(HttpContext.Current.User.Identity.Name);
}
}
public class MyRep
{
private readonly VtContext _context;
public MyRep(MyContext context)
{
_context = context;
}
... other repository code...
}
then just create a MyContext in your test:
var rep = new MyRep(new MyContext("unittest"));
I have an item and I am adding it to the database using this method:
public Messages addItem(Item item)
{
Messages resultMessage = Messages.Success;
using (IUnitOfWork unitOfWork = new UnitOfWork())
{
IItemRepository itemRep = new ItemRepository(unitOfWork);
try
{
itemRep.Insert(item);
unitOfWork.Commit();
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
resultMessage = Messages.DB_Failure;
}
}
return resultMessage;
}
Now I have to make write a unit test for this method to check if the item is being added to the database. I have no idea how I should do that, can someone help me?
Your code is coupled with the ItemRepository and the UnitOfWork implementations. Ideally you should decouple them and use mocks to verify that the right methods are called.
A possible solution:
Make the Repository a property on your unit of work
Don't create the Unit of Work directly, use a factory for that
Make the factory a dependency of your class
In your test pass a mock of the factory to the class you are testing that returns a mock of the Unit Of Work
Return a mock of the Repository on your UoW mock
Verify that the right methods are called on your Repository mock and Unit of Work mocks
This would be an example. I have used Moq as the mocking framework. And put the test method inside the class, but you can get the idea:
class MyClass
{
private readonly IUnitOfWorkFactory _factory;
public MyClass(IUnitOfWorkFactory factory)
{
_factory = factory;
}
public Messages addItem(Item item)
{
Messages resultMessage = Messages.Success;
using (IUnitOfWork unitOfWork = _factory.GetUnitOfWork())
{
try
{
unitOfWork.ItemRep.Insert(item);
unitOfWork.Commit();
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
resultMessage = Messages.DB_Failure;
}
}
return resultMessage;
}
public void Test()
{
// Arrange
var factoryMock = new Mock<IUnitOfWorkFactory>();
var uowMock = new Mock<IUnitOfWork>();
var repositoryMock = new Mock<IItemRepository>();
factoryMock.Setup(f => f.GetUnitOfWork()).Returns(uowMock.Object);
uowMock.Setup(u => u.ItemRep).Returns(repositoryMock.Object);
var sut = new MyClass(factoryMock.Object);
// Act
var item = new Item();
sut.addItem(item);
// Assert
repositoryMock.Verify(r => r.Insert(item), Times.Once);
uowMock.Verify(u => u.Commit(), Times.Once);
}
}
You say that the goal is to "check if this item is added to the database".
This is something you do not normally write a unit test for because it is the responsibility of the database, which presumably you are not the one developing.
A better case for a unit test is to mock out the database and check the logic that decides to add something to the database. For instance:
A Unit of Work is described by a customer/operator.
Your component queries the database for the existence of the item.
No corresponding item exists.
Your component adds the item to the database.
This is achieved by using just a mock of the database and it is testing your code, rather than the database.
As your method currently stands, it cannot be unit tested as it's hard-coded to write to the database.
The conventional way around this is to pass an instance of IItemRepository into the method, rather than having the method create it. Do that and then you are free to create a mocked IItemRepository implementation that can report what's being written to the DB.
As other answers suggested: try to separate your class under test from difficult/slow to test dependencies like the database. You can use a number of approaches to achieve this result, but they all come down to the same:
Don't create (new up) dependencies that make unit testing difficult in the code you want to test itself (like your unitofwork/repository). Rather, ask these dependencies from the outside world (google Dependency Inversion/DI for further info).
If you want to test the implementation of the repository with a real database, I suggest you test through the public API of your repository. Don't go writing "SELECT * FROM Items" queries yourself, but use a repository.GetItem(...) method if available. That way your tests are less brittle and decoupled from the actual implementation of your repository class.
My application is designed using the CQRS pattern and repositories, how can I create unit tests for my command classes without connecting to the database?
We are using Moq to create mocks of our repositories.
You have to mock your Database Layer. Similarly you can Mock Repositor layer also instead of Database Layer.
[TestClass]
public class TestCommandServiceTests
{
private readonly TestService _testService;
private readonly ITestRepositor _testRepository;
private readonly Mock<IDatabaseLaye> _mock;
[SetUp]
public void Setup()
{
_mock = new Mock<IDatabaseLayer>();
_testRepository = new TestRepository(_mock);
_testService = new TestService(_testRepository);
}
[Test]
public void TestMethod_ValidRequest_ShouldTestSuccessfully()
{
// Arrange
var request = new TestMethodRequest();
this._mock.Setup(c => c.TestSPMethod(null)).Returns(1000);
// Act
var response = _testService.TestMethod(request);
// Assert
Assert.IsNotNull(response);
Assert.AreEqual(1000, response.Id);
}
}
Of course you can mock the database (and you even should, says the textbook). But this soon gets very cumbersome, especially when complex database constraints are into play.
In practice it might be more productive to have a local test database (e.g. in-memory with SQLite or MS SQL CE, if possible) and test against the entire 'persistence stack' (in your case: Commands, Repositories AND database) in one go. This is the method that is recommended in the book The Art of Unit Testing, and I found it very helpful in practice.
I'm using LINQ-to-SQL with ASP.NET MVC 4, and as of this moment I have a repository layer which contacts a real database. This is not very good when I want to unit test.
Also there should never be a logic in the repository layer, so this is why I want to mock the LINQ DataContext so I can create a service layer that talks either to the mock DataContext or to the real DataContext.
I see that my LINQ DataContext class inherits DataContext, but there is no interface, so I can't really mock that. I also see that DataContext uses Table<> class and there exists an interface ITable, so I probably could mock that. Also my LINQ DataContext is a partial class, so maybe I could manipulate that in some kind of way?
When I google this, all articles are from 2008 and are outdated.
Can anyone guide me in the right appropriate direction?
Here is an example of what I want to do. I will have seperate service class for each controller.
public class MyServiceClass
{
IDataContext _context;
// Constructors with dependency injection
public MyServiceClass()
{
_context = new MyRealDataContext();
}
public MyServiceClass(IDataContext ctx)
{
_context = ctx;
}
// Service functions
public IEnumerable<ModelClass> GetAll()
{
return _context.ModelClass;
}
public ModelClass GetOne(int id)
{
return _context.Where(s => s.ID == id).SingleOrDefault();
}
}
Although Linq-to-Sql is still supported in .NET 4+, it has been pushed back in favor of Entity Framework. That's probably why you're finding mostly older articles.
Anyway the best way to go is to write your own DataAccess layer-interface, used through your application. You then can have an implementation of that interface that uses your linq-to-sql for production and a mocked implementation for your unit tests.
Use dependency injection to instantiate the actual implementation class.
For creating a mock implementation you do it either manually (Creating a class in your test project that implements the IDataContext interface but returns hard-coded data) or use one of the mocking frameworks around there.
I have not used every one of them but moq was quite nice. Microsoft has now also their framework in Visual Studio 2012 called Fakes, worth looking at.
Example of using moq
var expectedResultList = new List<ModelClass>(){ ... };
var mockDataContext = new Mock<IDataContext>();
mock.Setup(c => c.GetAll()).Returns(expectedResultList);
MyServiceClass service = new MyServiceClass(mockDataContext.Object);
var list = service.GetAll();
Assert.AreEqual(expectedResultList, list);
In this code you set up your mock object so that it will return your expected list when the GetAll method is called.
This way you can easily test your business logic based on different returns from your data access.
Example of IDataContext
public interface IDataContext<T>
{
IEnumerable<T> GetAll();
T GetById(int id);
int Save(T model);
}
public class LinqToSqlDataContext<T> : IDataContext<T>
{
private DataContext context = new DataContext();
public IEnumerable<T> GetAll()
{
// query datacontext and return enumerable
}
public T GetById(int id)
{
// query datacontext and return object
}
public int Save(T model)
{
// save object in datacontext
}
}
public class MyFirstServiceClass
{
private IDataContext<MyClass> context;
public MyFirstServiceClass(IDataContext<MyClass> ctx)
{
this.context = ctx;
}
....
}
public class MySecondServiceClass
{
private IDataContext<MySecondClass> context;
public MyFirstServiceClass(IDataContext<MySecondClass> ctx)
{
this.context = ctx;
}
....
}
How to perform a Unit testing on MVC application?
I have created the Controller Location.
It has properties like LocationName,Area,City,PinCode.
Now, I want to perform unit test to check whether Location saves in DB or not.
How to check it.
I have go through tons of videos, every where they just put the Unit test of
Mathematical operations like adding,Dividing , subtracting....
I would like to know how to perform the Unit testing of Create method of MVC
I have code something like below
[HttpPost]
public ActionResult Create(Location location)
{
if (ModelState.IsValid)
{
db.Locations.Add(location);
db.SaveChanges();
return RedirectToAction("Index");
}
}
In order to make your code testable, you should abstract dependencies of controller. It's very handy to use Repository pattern to abstract data access. Inject your repository into controller:
public class LocationController : Controller
{
private ILocationRepository _locationRepository;
public LocationController(ILocationRepository locationRepository)
{
_locationRepository = locationRepository;
}
}
Now you can mock your repository. Here is sample test with Moq framework and MvcContrib:
// Arrange
Mock<ILocationRepository> repository = new Mock<ILocationRepository>();
var controller = new LocationController(repository.Object);
Location location = new Location("New York);
// Act
var result = controller.Create(location);
// Assert
result.AssertActionRedirect()
.ToAction<LocationController>(c => c.Index());
repository.Verify(r => r.Add(location));
repository.Verify(r => r.Save());
And you can implement code, which will pass this test:
[HttpPost]
public ActionResult Create(Location location)
{
if (ModelState.IsValid)
{
_locationRepository.Add(location);
_locationRepository.Save();
return RedirectToAction("Index");
}
}
You can read more on implementing repositories and testing MVC applications here:
Implementing the Repository and Unit of Work Patterns in an ASP.NET MVC Application. Nice feature also to have Unit of Work per request.