I am exploring CodeCamper project by JohnPapa on github
https://github.com/johnpapa/CodeCamper. This is a ASP.Net SPA application and I am also working on similar project.
I interested to write some UnitTests for WebAPI controller. Controller contractor requires UnitofWork instanse and UnitofWork is initiate in Application_Start method.
When I run my UnitTest project UnitofWork object is null. How I can initiate UnitofWork from UnitTest project so that I can run my test methods. I hope make myself clear.
Here is a sample UnitTest method for following controller.
LookupsController.cs
UserControllerTest.cs
[TestClass]
public class UserControllerTest : ApiBaseController
{
[TestMethod]
public void GetRoomsTest()
{
var controller = new LookupsController(Uow);
var result = controller. GetRooms().Any();
Assert.IsTrue(result);
}
}
Again why Uow is null? What should I do, so that I can write unit test methods for this type of project/architecture.
For more detail about code you can check github repo.https://github.com/johnpapa/CodeCamper
Use any mocking framework to create a fake/stub/mock for ICodeCamperUow (below I am using NSubstitute):
[TestMethod]
public void GetRoomsTest()
{
// UOW we need to use
var fakeUOW = Substitute.For<ICodeCamperUow>();
// setting up room repository so that it returns a collection of one room
var fakeRooms = Substitute.For<IRepository<Room>>();
var fakeRoomsQueryable = new[]{new Room()}.AsQueryable();
fakeRooms.GetAll<Room>().Returns(fakeRoomsQueryable);
// connect UOW with room repository
fakeUOW.Rooms.Returns(fakeRooms);
var controller = new LookupsController(fakeUOW);
var result = controller.GetRooms().Any();
Assert.IsTrue(result);
}
Please consider reading The Art of Unit Testing which is a great book to learn about unit testing.
Related
this test always return null, and test always fail...but when i run the projet all works fine and return data normally, this project using RavenDB
Controller
[Route("api/[controller]")]
public class CategoryController : Controller
{
private readonly AppDbContext _context = new AppDbContext();
// GET: api/category
[HttpGet("{id}")]
public async Task<JsonResult> Get(string id)
{
using (IAsyncDocumentSession session = _context.SessionAsync){
var result = await session.LoadAsync<Category>(id);
return Json(result);
}
}
}
and using xUnit to testing
[Fact]
public async Task GetShouldReturnCategory()
{
// Arrange
var _categoryController = Substitute.For<CategoryController>();
var category = CreateCategory();
// Act
var result = await _categoryController.Get(category.Result.Id);
//Asserts here
}
Base on your question, system under test (SUT) is CategoryController. So, it doesn't make sense to mock CategoryController; instead, you want to mock AppDbContext.
If you want to unit test a controller, you should use ASP.NET Core's Dependency Inject, and inject its dependencies via constructor injection. In other words, you should not use new.
Normally, we inject interface instead of concrete class, so that we can easily mock it.
Your code is missing too many pieces, so I could only give you a directly. You want more detail you can look at this sample project at GitHub which uses NSubstitute and XUnit.
I recently took a .Net project over which exposes DAOs from a Microsoft SQL Database via ServiceStack(3.9.71) REST API. Since I am gonna refactor some parts I want to unit test (at least) all servicestack services. For a better understanding I quickly draft how the implementation works.
Each Service contains a property of type DBService which encapsulates all database accesses of all services. Unfortunately this is a concrete class which makes it hard to mock. The DI.Container wrappes ServiceStack's IOC.
public class SomeService : Service
{
public DBService { get { return DI.Container.Resolve<DBService>(); } }
public object Get(SomeDataClass class)
{
var response = DBService.SomeServiceGet();
return response;
}
// other code omitted
}
The DBService looks like this (draft):
public class DBService
{
public IDbConnectionFactory DBFactory { get { return DI.Container.Resolve<IDbConnectionFactory>(); } }
public SomeServiceResponse SomeServiceGet()
{
//DB Access here...
// ...
}
public SomeOtherServiceResponse SomeOtherServiceGet()
{
//...
}
// following about 30 other methods for all the services (POST,GET,PUT etc)
}
I read the detailed response to this question but I was not able to create and initialize a BasicAppHost in ServiceStack 3.9.71 since it immediately threw a System.TypeLoadExceptionMethod 'get_VirtualPathProvider'.
On the other hand I was thinking that I do not actually need a BasicAppHost. I just have to unit test the DBService and then the servicestack services with a somehow mocked DBService. The only problem I have is that DBService is not an interface and that I am actually not sure how to deal (mock) with the SQL database and the IOC.
[UPDATE]
Unfortunately I am still not able to test a service since I can not just new the service in my test. If I do so I get:
System.TypeLoadExceptionCould not load type 'ServiceStack.ServiceHost.IService' from assembly
Here is my test:
[Fact]
public void SomeDataTest()
{
var serviceUnderTest = new SomeService();
var response = serviceUnderTest.Get(new SomeDataClass());
Assert.NotNull(response);
}
I guess the problem is that the services strongly uses alot of properties which are injected via the IOC. How can I mock that? Creating a BasicAppHost and retrieving the service from there also does not work which I already mentioned.
If you are just testing your service class, then you can directly mock any dependencies:
[Fact]
public void SomeDataTest(
{
var serviceUnderTest = new SomeService();
var logger = new Mock<ILogger>(); // Rhino mocks fashion.
serviceUnderTest.Logger = logger.Object;
var response = serviceUnderTest.Get(new SomeDataClass());
Assert.NotNull(response);
}
There's an page in their older docs here about integration testing in case you want to test the AppHost
Edit: there's an example of mocking the service dependencies here.
-------Please see updates below as I now have this set up for dependency injection and the use of the MOQ mocking framework. I'd still like to split up my repository so it doesn't directly depend on pulling the windowsUser within the same function.
I have a Web API in an intranet site that populates a dropdown. The query behind the dropdown takes the windows username as a parameter to return the list.
I realize I don't have all of this set up correctly because I'm not able to unit test it. I need to know how this "should" be set up to allow unit testing and then what the unit tests should look like.
Additional info: this is an ASP.NET MVC 5 application.
INTERFACE
public interface ITestRepository
{
HttpResponseMessage DropDownList();
}
REPOSITORY
public class ExampleRepository : IExampleRepository
{
//Accessing the data through Entity Framework
private MyDatabaseEntities db = new MyDatabaseEntities();
public HttpResponseMessage DropDownList()
{
//Get the current windows user
string windowsUser = HttpContext.Current.User.Identity.Name;
//Pass the parameter to a procedure running a select query
var sourceQuery = (from p in db.spDropDownList(windowsUser)
select p).ToList();
string result = JsonConvert.SerializeObject(sourceQuery);
var response = new HttpResponseMessage();
response.Content = new StringContent(result, System.Text.Encoding.Unicode, "application/json");
return response;
}
}
CONTROLLER
public class ExampleController : ApiController
{
private IExampleRepository _exampleRepository;
public ExampleController()
{
_exampleRepository = new ExampleRepository();
}
[HttpGet]
public HttpResponseMessage DropDownList()
{
try
{
return _exampleRepository.DropDownList();
}
catch
{
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
}
}
}
UPDATE 1
I have updated my Controller based on BartoszKP's suggestion to show dependency injection.
UPDATED CONTROLLER
public class ExampleController : ApiController
{
private IExampleRepository _exampleRepository;
//Dependency Injection
public ExampleController(IExampleRepository exampleRepository)
{
_exampleRepository = exampleRepository;
}
[HttpGet]
public HttpResponseMessage DropDownList()
{
try
{
return _exampleRepository.DropDownList();
}
catch
{
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
}
}
}
UPDATE 2
I have decided to use MOQ as a mocking framework for unit testing. I'm able to test something simple, like the following. This would test a simple method that doesn't take any parameters and doesn't include the windowsUser part.
[TestMethod]
public void ExampleOfAnotherTest()
{
//Arrange
var mockRepository = new Mock<IExampleRepository>();
mockRepository
.Setup(x => x.DropDownList())
.Returns(new HttpResponseMessage(HttpStatusCode.OK));
ExampleController controller = new ExampleController(mockRepository.Object);
controller.Request = new HttpRequestMessage();
controller.Configuration = new HttpConfiguration();
//Act
var response = controller.DropDownList();
//Assert
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
I need help testing the DropDownList method (one that does include code to get the windowsUser). I need advice on how to break this method apart. I know both parts shouldn't been in the same method. I don't know how to arrange splitting out the windowsUser variable. I realize this really should be brought in as a parameter, but I can't figure out how.
You usually do not unit-test repositories (integration tests verify if they really persist the data in the database correctly) - see for example this article on MSDN:
Typically, it is difficult to unit test the repositories themselves, so it is often better to write integration tests for them.
So, let's focus on testing only the controller.
Change the controller to take IExampleRepository in its constructor as a parameter:
private IExampleRepository _exampleRepository;
public ExampleController(IExampleRepository exampleRepository)
{
_exampleRepository = exampleRepository;
}
Then, in your unit tests, use one of mocking frameworks (such as RhinoMock for example) to create a stub for the sole purpose of testing the controller.
[TestFixture]
public class ExampleTestFixture
{
private IExampleRepository CreateRepositoryStub(fake data)
{
var exampleRepositoryStub = ...; // create the stub with a mocking framework
// make the stub return given fake data
return exampleRepositoryStub;
}
[Test]
public void GivenX_WhenDropDownListIsRequested_ReturnsY()
{
// Arrange
var exampleRepositoryStub = CreateRepositoryStub(X);
var exampleController = new ExampleController(exampleRepositoryStub);
// Act
var result = exampleController.DropDownList();
// Assert
Assert.That(result, Is.Equal(Y));
}
}
This is just a quick&dirty example - CreateRepositoryStub method should be of course extracted to some test utility class. Perhaps it should return a fluent interface to make the test's Arrange section more readable on what is given. Something more like:
// Arrange
var exampleController
= GivenAController()
.WithFakeData(X);
(with better names that reflect your business logic of course).
In case of ASP.NET MVC, the framework needs to know how to construct the controller. Fortunately, ASP.NET supports the Dependency Injection paradigm and a parameterless constructor is not required when using MVC unity.
Also, note the comment by Richard Szalay:
You shouldn't use HttpContext.Current in WebApi - you can use base.User which comes from HttpRequestBase.User and is mockable. If you really want to continue using HttpContext.Current, take a look at Mock HttpContext.Current in Test Init Method
One trick that I find very useful when trying to make old code testable when said code is accessing some global static or other messy stuff that I can't easily just parameterize is to wrap access to the resource in a virtual method call. Then you can subclass your system under test and use that in the unit test instead.
Example, using a hard dependency in the System.Random class
public class Untestable
{
public int CalculateSomethingRandom()
{
return new Random().Next() + new Random().Next();
}
}
Now we replace var rng = new Random();
public class Untestable
{
public int CalculateSomethingRandom()
{
return GetRandomNumber() + GetRandomNumber();
}
protected virtual int GetRandomNumber()
{
return new Random().Next();
}
}
Now we can create a testable version of the class:
public class Testable : Untestable
{
protected override int GetRandomNumber()
{
// You can return whatever you want for your test here,
// it depends on what type of behaviour you are faking.
// You can easily inject values here via a constructor or
// some public field in the subclass. You can also add
// counters for times method was called, save the args etc.
return 4;
}
}
The drawback with this method is that you can't use (most) isolation frameworks to implement protected methods (easily), and for good reason, since protected methods are sort of internal and shouldn't be all that important to your unit tests. It's still a really handy way of getting things covered with tests so you can refactor them, instead of having to spend 10 hours without tests, trying to do major architectual changes to your code before you get to "safety".
Just another tool to keep in mind, I find it comes in handy from time to time!
EDIT: More concretely, in your case you might want to create a protected virtual string GetLoggedInUserName(). This will technically speaking keep the actual call to HttpContext.Current.User.Identity.Name untested, but you will have isolated it to the simplest smallest possible method, so you can test that the code is calling the correct method the right amount of times with the correct args, and then you simply have to know that HttpContext.Current.User.Identity.Name contains what you want. This can later be refactored into some sort of user manager or logged in user provider, you'll see what suits best as you go along.
I have a MVC3 project that uses property injection. Within my controllers I make a call to a service class. As I mentioned it uses property injection (with unity) instead of resolving this through the constructor. I have searched all over trying to find an example of a unit test that resolves these dependencies within my controller but everything seems to refer to constructer DI. I’m getting frustrated. Any help would be great.
Example of Controller:
[Dependency]
public ITrainingService trainingService { get; set; }
public ActionResult Index(MyTrainingView myTrainingView)
{
//Load all training items into view object
myTrainingView.training = trainingService.getTraining(myTrainingView.trainingId);
myTrainingView.videos = trainingService.getTrainingVideos(myTrainingView.trainingId);
myTrainingView.visuals = trainingService.getTrainingVisuals(myTrainingView.trainingId);
myTrainingView.exams = trainingService.getTrainingExams(myTrainingView.trainingId);
return View(myTrainingView);
}
I'm trying to resolve the trainingService when running my unit test. I have found countless examples for mocking and resolving dependencies using constructor dependency but nothing when it comes to property injection.
You don't need to rely on unity in your unit tests.
Something like this would do the trick:
[Test]
public void GetTrainingById()
{
var mockService = MockRepository.GenerateMock<ITrainingService>();
mockService.Stub(service => service.getTraining(123)).Return(new ImaginaryClass());
var sut = new TrainingController();
sut.trainingService = mockService;
var myTrainingView = new MyTrainingView();
sut.Index(myTrainingView);
Assert.AreEqual(expected, myTrainingView.training);
}
If you must use unity in your unit tests, you could just instantiate the UnityContainer in your test and use the RegisterInstance to register the objects you want to inject.
I am using .NET 4, NUnit and Rhino mocks. I want to unit test my news repository, but I am not sure of how to go about it. My news repository is what I will eventually be using to communicate to the database. I want to use it to test against fake/dummy data. Not sure if it is possible?? This is what I currently have:
public interface INewsRepository
{
IEnumerable<News> FindAll();
}
public class NewsRepository : INewsRepository
{
private readonly INewsRepository newsRepository;
public NewsRepository(INewsRepository newsRepository)
{
this.newsRepository = newsRepository;
}
public IEnumerable<News> FindAll()
{
return null;
}
}
My unit test looks like this:
public class NewsRepositoryTest
{
private INewsRepository newsRepository;
[SetUp]
public void Init()
{
newsRepository = MockRepository.GenerateMock<NewsRepository>();
}
[Test]
public void FindAll_should_return_correct_news()
{
// Arrange
List<News> newsList = new List<News>();
newsList.Add(new News { Id = 1, Title = "Test Title 1" });
newsList.Add(new News { Id = 2, Title = "Test Title 2" });
newsRepository.Stub(r => r.FindAll()).Return(newsList);
// Act
var actual = newsRepository.FindAll();
// Assert
Assert.AreEqual(2, actual.Count());
}
}
In the above code I am not sure what I need to mock. The code above compiles but fails in the NUnit GUI about a contructor value. I can only assume it has to do with the INewsRepository paramter that I need to supply to NewsRepository. I don't know how to do this in the test. Can someone please rectify my unit test so that it will pass in the NUnit GUI? Can someone also provide some feedback on if I am implementing my repositories correctly?
Being a newbie to mocking, is there anything that I need to verify? When would I need to verify? What is its purpose? I have been working through a couple of source code projects and some use verify and some don't.
If the above test passes, what does this prove to me as developer? What does another developer have to do to my repository to make it fail in the NUnit GUI?
Sorry for all the questions, but they are newbie questions :)
I hope soomeone can help me out.
As Steven has said, you're Asserting against the Mock NewsRepository in the above code.
The idea of mocking is to isolate the Code Under Test and to create fakes to replace their dependencies.
You use the Mock NewsRepository to test something that uses INewsRepository, in your case, you mention NewsService; NewsService will use your mock of INewsRepository.
If you search your solution for anything that uses INewsRepository.FindAll(), you will create a Mock Repository to test that code in isolation.
If you want to test something that calls your Service layer, you will need to mock NewsService.
Also, as Steven as said, there is no need for the NewsRepository to have a copy of itself injected by IoC, so:
public class NewsRepository : INewsRepository
{
private readonly INewsRepository newsRepository;
public NewsRepository(INewsRepository newsRepository)
{
this.newsRepository = newsRepository;
}
public IEnumerable<News> FindAll()
{
return null;
}
}
should become:
public class NewsRepository : INewsRepository
{
public IEnumerable<News> FindAll()
{
return null;
}
}
Once you have functionality in your FindAll() method that needs testing, you can mock the objects that they use.
As a point of style from the great Art Of Unit Testing initialisation of mock objects is best left out of the Setup method and carried out in a helper method called at the start of the method. Since the call to Setup will be invisible and makes the initalisation of the mock unclear.
As another point of style, from that book, a suggested unit test naming convention is: "MethodUnderTest_Scenario_ExpectedBehavior".
So,
FindAll_should_return_correct_news
could become, for example:
FindAll_AfterAddingTwoNewsItems_ReturnsACollectionWithCountOf2
I hope this makes the approach clearer.
Your FindAll_should_return_correct_news test method is not testing the repository, it is testing itself. You can see this when you simplify it to what it really does:
[Test]
public void FindAll_should_return_correct_news()
{
// Arrange
List<News> newsList = new List<News>();
newsList.Add(new News { Id = 1, Title = "Test Title 1" });
newsList.Add(new News { Id = 2, Title = "Test Title 2" });
// Act
var actual = newsList;
// Assert
Assert.AreEqual(2, actual.Count());
}
As you can see, what you're basically doing is creating a list, filling it and testing if it actually contains the number of records that you put in it.
When your repository does nothing else than database interaction (so no application logic) there is nothing to test using a unit test. You can solve this problem by writing integration tests for the repositories. What you can basically do with such a integration test is insert some records in a test database (use a real database though, not an in-memory database) and then call the real repository class to see if it fetches the expected records from your test database. All should be executed within a transaction and rolled back at the end of the test (this ensures these tests keep trustworthy).
When you're using a O/RM tool that allows you to write LINQ queries, you could also try a different approach. You can fake your LINQ provider, as you can see in this article.
Might want to read over this post by ayende