Controller API Testing with xUnit/Moq - Controller is null - c#

I'm new to unit testing, so my problem is probably with my code and not the Moq framework, but here goes.
I'm using .Net Core with xUnit and the Moq framework, and I'm more or less following instructions from their documentation. I'm trying to test route api/user to get all users, and the issue was on asserting that the response was an ObjectResult containing <IEnumerable<User>>. No matter what I tried, result.Value was always null. The first assertion passes fine.
I set up a console project to debug this, and found something interesting. that value of the controller in the test method in Visual Studio is null. In VS Code, the value in the debugger shows Unknown Error: 0x00000....
Below is the test:
public class UserControllerTests {
[Fact]
public void GetAll_ReturnsObjectResult_WithAListOfUsers() {
// Arrange
var mockService = new Mock<IUserService>();
var mockRequest = new Mock<IServiceRequest>();
mockService.Setup(svc => svc.GetUsers(mockRequest.Object))
.Returns(new ServiceRequest(new List<User> { new User() }));
var controller = new UserController(mockService.Object);
// Act
var result = controller.GetAll();
// Assert
Assert.IsType<ObjectResult>(result);
Assert.IsAssignableFrom<IEnumerable<User>>(((ObjectResult)result).Value);
}
}
And here is the controller:
public class UserController : Controller {
private IUserService service;
public UserController(IUserService service) {
this.service = service;
}
[HttpGet]
public IActionResult GetAll() {
var req = new ServiceRequest();
service.GetUsers(req);
if(req.Errors != null) return new BadRequestObjectResult(req.Errors);
return new ObjectResult(req.EntityCollection);
}
}
And the Service Layer:
public interface IUserService {
IServiceRequest GetUsers(IServiceRequest req);
}
public class UserService : IUserService {
private IUserRepository repo;
public IServiceRequest GetUsers(IServiceRequest req) {
IEnumerable<User> users = null;
try {
users = repo.GetAll();
}
catch(MySqlException ex) {
req.AddError(new Error { Code = (int)ex.Number, Message = ex.Message });
}
finally {
req.EntityCollection = users;
}
return req;
}
}
public interface IServiceRequest {
IEnumerable<Object> EntityCollection { get; set; }
List<Error> Errors { get; }
void AddError(Error error);
}
public class ServiceRequest : IServiceRequest {
public IEnumerable<Object> EntityCollection { get; set; }
public virtual List<Error> Errors { get; private set; }
public ServiceRequest () { }
public void AddError(Error error) {
if(this.Errors == null) this.Errors = new List<Error>();
this.Errors.Add(error);
}
}
Like I said, it's probably something I'm doing wrong, I'm thinking in the mockService.Setup() but I'm not sure where. Help please?

From the use of service.GetUsers(req) it looks like service is suppose to populate the service request but in your setup you have it returning a service request. A result which is also not used according to your code.
You need a Callback to populate whatever parameter is given to the service in order to mock/replicate when it is invoked. Since the parameter is being created inside of the method you will use Moq's It.IsAny<> to allow the mock to accept any parameter that is passed.
var mockService = new Mock<IUserService>();
mockService.Setup(svc => svc.GetUsers(It.IsAny<IServiceRequest>()))
.Callback((IServiceRequest arg) => {
arg.EntityCollection = new List<User> { new User() };
});
This should allow the method under test to flow through it's invocation and allow you to assert the outcome.

Related

How to do integration test with MediatR using Moq in C#?

I am new to Integration test, I have a controller which has IMediator and I am using Moq framework for the integration test.
The issue I am having is that I keep getting null in the response when trying to mock MediatR. Before trying to mock MediatR, I tried to mock a service (in this case IUserService) and it worked perfectly (the return type for the Delete controller and other methods was bool).
Since I am now using IMediator in the controller so trying to change the integration test to mock MediatR, I can do integration test for the handler which has IUserService but I am trying to test the whole pipeline. Below is what I have in terms of code starting from the controller to the integration test.
//Controller
private IMediator _mediator;
public UserController(IMediator mediator)
{
_mediator = mediator;
}
[HttpDelete("{id}")]
public async Task<ActionResult<Result<Unit>>> DeleteUser(int id)
{
return await _mediator.Send(new DeleteUserCommand { UserId = id });
}
public class DeleteUserCommand : IRequest<Result<Unit>> {public int UserId { get; set; }}
//Command handler
public class DeleteUserCommandHandler : IRequestHandler<DeleteUserCommand, Result<Unit>>
{
private readonly IUserService _userService;
public DeleteUserCommandHandler(IUserService userService)
{
_userService = userService;
}
public async Task<Result<Unit>> Handle(DeleteUserCommand request, CancellationToken cancellationToken)
{
return await _userService.DeleteUser(request.UserId);
}
}
//Service layer
public async Task<Result<Unit>> DeleteUser(int userId)
{
var userExist = await _context.Users.FirstOrDefaultAsync(x => x.Id == userId);
if (userExist == null) return Result<Unit>.Failure("User Id doesn't exsist");
_context.Remove(userExist);
var result = await _context.SaveChangesAsync() > 0;
return Result<Unit>.Success(Unit.Value);
}
//Integration test
[TestFixture]
public class UserControllerTests
{
private readonly Mock<IMediator> _mockMediator;
private UserController _userController;
public UserControllerTests()
{
_mockMediator = new Mock<IMediator>();
}
[Test]
public async Task DeleteUser_NotSuccessful_NoIdDeleted()
{
Result<Unit> expected = new Result<Unit>();
_mockMediator.Setup(x => x.Send(It.IsAny<DeleteUserCommand>(), It.IsAny<CancellationToken>()))
.Returns(Task.FromResult(expected));
_userController = new UserController(_mockMediator.Object);
var result = await _userController.DeleteUser(6);
Assert.AreEqual("User Id doesn't exsist", result?.Value?.Error);
}
}
//Response in the integration test
I have two UserIds 6 and 7
UserId 6: doesn't exsist so I am expecting a message saying id doesn't exsist but the current response I am getting is null.
UserId 7: does exsist and expecting something like IsSuccess: true which is a custom code I added
Note: the attached code for the test is just for user Id 6.
You might notice in the code above starting from the controller, part of the return type is Result which is a custom class I added and below is the code.
public class Result<T>
{
public bool IsSuccess { get; set; }
public T Value { get; set; }
public string Error { get; set; }
public static Result<T> Success(T value) => new Result<T> { IsSuccess = true, Value = value };
public static Result<T> Failure(string error) => new Result<T> { IsSuccess = false, Error = error };
}
`
I am trying to find out what I have done wrong with mocking MediatR and why it keep returning null.
Thanks for the help in advance.
First thing I tried to do integration test mock the IUserService then switched to IMediator then started to get null in the response when doing integration test. I tried to google the issue but no luck.

Mocked controller object method returns Null value in Result

I am using xUnit tool to write unit test cases in Dot net core. Here in this example, I am also trying to mock protected method of the controller.
public interface ITestService {
string GetString(string testString);
}
public class TestModel {
string testValue { get; set; }
}
public class TestController : Controller
{
readonly ITestService testService;
public TestController() {
}
public TestController(ITestService _testService) {
testService = _testService;
}
[HttpPost]
public async Task<IActionResult> Post([FromBody]TestModel testModel)
{
string test = GetString("testNew");
await Task.Run(() => "test");
return Ok(test);
}
protected virtual string GetString(string testString)
{
return "test" + testString;
}
}
Therefore, I will need to mock the controller itself to get protected method unit tested in its calling method.
But I am getting Null value when I call controller's method using Mocked object.
public class TestControllerTest
{
private Mock<ITestService> MockTestService { get; }
TestController controller { get; }
public TestControllerTest()
{
MockTestService = new Mock<ITestService>();
controller = new TestController(MockTestService.Object);
}
[Fact]
public void Post_TakesTestString_ReturnsString()
{
var MockController = new Mock<TestController>(MockTestService.Object);
MockController.Protected().Setup<string>("GetString", ItExpr.IsAny<string>()).Returns("testMockValue").Verifiable();
var result = MockController.Object.Post(new TestModel() { }).Result;
// result returns NULL value
MockController.Protected().Verify("GetString", Times.Once(), ItExpr.IsAny<string>());
}
}
My issue is on below line in code -
var result = MockController.Object.Post(new TestModel() { }).Result;
Which returns Null value, I expect, line should return OkObjectResult with test string.
As the subject class under test is also being mocked, the actual target method needs to be invoked.
Enable that with CallBase property set to true otherwise the default behavior is to return null for members not setup to be called.
For example
public class TestControllerTest {
[Fact]
public async Task Post_TakesTestString_ReturnsString() {
//Arrange
var MockTestService = new Mock<ITestService>();
var MockController = new Mock<TestController>(MockTestService.Object) {
CallBase = true //<--
};
MockController.Protected().Setup<string>("GetString", ItExpr.IsAny<string>()).Returns("testMockValue").Verifiable();
TestController controller = MockController.Object;
//Act
var result = await controller.Post(new TestModel() { });
//Assert
MockController.Protected().Verify("GetString", Times.Once(), ItExpr.IsAny<string>());
}
}

Mock setup returning null when the method is called using await

I'm trying to unit test an action in an MVC controller but the mocked object is returning null.
I have a ClientProxy interface
public interface IClientProxy
{
Task<T> Get<T>(string uri);
}
With the following concrete implementation
public async Task<T> Get<T>(string uri)
{
using (HttpClient httpClient = new HttpClient())
{
ConfigureClient(httpClient);
var response = await httpClient.GetAsync(uri);
response.EnsureSuccessStatusCode();
return await Task.Run(() => GetResultFromResponse<T>(response));
}
}
This is my action
public async Task<ActionResult> Index()
{
var categories = await _proxy.Get<PagedResults<Category>>("/category/get");
return View("index", null, JsonConvert.SerializeObject(categories));
}
And this is the unit test class
public class CategoryControllerTests
{
private readonly CategoryController _controller;
private readonly Mock<IClientProxy> _mockProxy;
public CategoryControllerTests()
{
_mockProxy = new Mock<IClientProxy>();
_controller = new CategoryController(_mockProxy.Object);
}
[Fact]
public async Task IndexPageRenders()
{
// Arrange
var fakeResult = new PagedResults<Category>
{
Paging = new Paging
{
Page = 1,
PageSize = 10,
TotalRecords = 2
},
Results = new List<Category>
{
new Category { CategoryId = 1, Name = "Category One" },
new Category { CategoryId = 2, Name = "Category Two" }
}
};
var result = JsonConvert.SerializeObject(fakeResult);
_mockProxy.Setup(p => p.Get<PagedResults<Category>>(It.IsAny<string>())).ReturnsAsync(fakeResult);
// Act
var action = await _controller.Index() as ViewResult;
// Assert
_mockProxy.Verify(p => p.Get<PagedResults<Category>>(It.IsAny<string>()), Times.Exactly(1));
}
}
Currently the mocked object setup for the get method is not getting hit, and categories are null (the Verify is failing, implying that the mocked method is never called). However, if I remove the await keyword from the action then the categories are returned. I'd rather not remove the await just to pass the test as it's there for a good reason, so any help would be appreciated.
Thanks in advance.
Currently the mocked object setup for the get method is not getting hit, and categories are null (the Verify is failing, implying that the mocked method is never called).
That would mean that the mocked object was not passed as a dependency to the controller being tested and as such is not being invoked when the test is being exercised.
Here is a Minimal, Complete, and Verifiable example that demonstrates how one would setup and exercise a test in such a scenario.
The follow were used
public class MyModel {
public int MyIntProperty { get; set; }
public string MyStringProperty { get; set; }
}
public interface IClientProxy {
Task<T> Get<T>(string uri);
}
public class MyController : Controller {
IClientProxy _proxy;
public MyController(IClientProxy _proxy) {
this._proxy = _proxy;
}
public async Task<ActionResult> Index() {
var categories = await _proxy.Get<MyModel>("/category/get");
return View(categories);
}
}
And following test was used with MSTest, Moq and Fluent Assertions where is flowed to completion and passed.
[TestClass]
public class MyController_Should {
[TestMethod]
public async Task _Render_Index_Page() {
// Arrange
var fakeResult = new MyModel {
MyIntProperty = 0,
MyStringProperty = "Hello World."
};
var _mockProxy = new Mock<IClientProxy>();
_mockProxy
.Setup(_ => _.Get<MyModel>(It.IsAny<string>()))
.ReturnsAsync(fakeResult);
var _controller = new MyController(_mockProxy.Object);
// Act
var action = await _controller.Index() as ViewResult;
// Assert
_mockProxy.Verify(_ => _.Get<MyModel>(It.IsAny<string>()), Times.Exactly(1));
action.Should().NotBeNull();
var model = action.Model;
model.Should().NotBeNull()
.And.BeOfType<MyModel>()
.And.Be(fakeResult);
}
}
I would suggest reviewing this example and then comparing it to how you designed your test to see if you can identify what may be causing your problem.

How to Unit Test a GlassController Action without SitecoreContext Dependency Injection

I'm a sitecore developer, and I want to create a sample sitecore helix unit testing project for testing out the exact below Index() action method of our "HomeBottomContentController" controller, without any dependency injection into a constructor. Note that the commented-out code is exactly what I do NOT want to do.
public class HomeBottomContentController : GlassController
{
// I want to test the EXACT method below
public override ActionResult Index()
{
var context = new SitecoreContext();
var model = context.GetCurrentItem<Home_Control>();
return View("~/Views/HomeBottomContent/HomeBottomContent.cshtml", model);
}
/*
// I do NOT want to have any of the below code for injecting ISitecoreContext into a constructor and testing the IndexTest() below it.
private readonly ISitecoreContext _iSitecoreContext;
public HomeBottomContentController(ISitecoreContext iSitecoreContext)
{
_iSitecoreContext = iSitecoreContext;
}
public HomeBottomContentController()
{ }
public ActionResult IndexTest()
{
var model = _iSitecoreContext.GetCurrentItem<Home_Control>();
return View("~/Views/HomeBottomContent/HomeBottomContent.cshtml", model);
}
*/
}
Here's what I have in my unit testing class. Again, what I have commented out exactly what I don't want to do:
[TestClass]
public class MvcUnitTests
{
[TestMethod]
public void Test_HomeBottomContentController_With_ISitecoreContext()
{
/*
// I don't want to do below...
var model = new Home_Control()
{ Bottom_Content = "XYZ" };
var iSitecoreContext = new Mock<Glass.Mapper.Sc.ISitecoreContext>();
iSitecoreContext.Setup(_ => _.GetCurrentItem<Home_Control>(false, false)).Returns(model);
HomeBottomContentController controllerUnderTest = new HomeBottomContentController(iSitecoreContext.Object);
var result = controllerUnderTest.IndexTest() as ViewResult;
*/
//I want to test using the exact constructor below and calling that exact Index() method.
HomeBottomContentController controllerUnderTest = new HomeBottomContentController();
var result = controllerUnderTest.Index() as ViewResult;
Assert.IsNotNull(result);
Assert.IsNotNull(result.Model);
//Assert.AreEqual(((Home_Control)result.Model).Bottom_Content, "XYZ");
}
}
How can I test my controller's exact Index() method without having to add code to the HomeBottomContentController class that enables dependency injection into a constructor (like the commented-out code above)? I do not want to have to add code to HomeBottomContentController().
#Aleksey Shevchenko If I try your solution, how do I exactly hook up the model to the iSitecoreContext and then assign that to the controllerUnderTest.FakeContext? My code below throws compilation error (You cannot convert from Mock of Glass.Mapper.Sc.ISitecoreContext to Glass.Mapper.Sc.ISitecoreContext, how do we accomplish that):
var model = new Home_Control()
{ Top_Content = "Some Dummy Test Home Top Content" };
var iSitecoreContext = new Mock<Glass.Mapper.Sc.ISitecoreContext>();
//var iSitecoreContext = new Glass.Mapper.Sc.SitecoreContext();
iSitecoreContext.Setup(_ => _.GetCurrentItem<Home_Control>(false, false)).Returns(model);
FakeHomeTopContentController controllerUnderTest = new FakeHomeTopContentController();
controllerUnderTest.FakeContext = (Glass.Mapper.Sc.SitecoreContext)iSitecoreContext;
If you don't want to create dependency injection through constructor you can do that through protected virtual method. Something like that:
public class HomeBottomContentController : GlassController
{
public override ActionResult Index()
{
var context = this.GetContext();
var model = context.GetCurrentItem<Home_Control>();
return View("~/Views/HomeBottomContent/HomeBottomContent.cshtml", model);
}
protected virtual SitecoreContext GetContext()
{
return new SitecoreContext();
}
}
[TestClass]
public class MvcUnitTests
{
[TestMethod]
public void Test_HomeBottomContentController_With_ISitecoreContext()
{
var controllerUnderTest = new FakeHomeBottomContentController();
controllerUnderTest.FakeContext = /* set what you want */;
var result = controllerUnderTest.Index() as ViewResult;
Assert.IsNotNull(result);
Assert.IsNotNull(result.Model);
}
public class FakeHomeBottomContentController : HomeBottomContentController
{
public SitecoreContext FakeContext { get; set; }
protected override SitecoreContext GetContext()
{
return this.FakeContext;
}
}
}
I don't know the limitations of your ability to end the source code but based on your comment to the other answer you have access to it. I would opt for Poor Man's DI, have two constructors on the controller. The unit test uses the second constructor and MVC will use the parameterless constructor.
public class HomeBottomContentController : GlassController
{
ISitecoreContext _iSitecoreContext;
public HomeBottomContentController() :this(new SitecoreContext()){
}
public HomeBottomContentController(ISitecoreContext iSitecoreContext)
{
_iSitecoreContext = iSitecoreContext;
}
public ActionResult IndexTest()
{
var model = _iSitecoreContext.GetCurrentItem<Home_Control>();
return View("~/Views/HomeBottomContent/HomeBottomContent.cshtml", model);
}
}
[TestClass]
public class MvcUnitTests
{
[TestMethod]
public void Test_HomeBottomContentController_With_ISitecoreContext()
{
var model = new Home_Control()
{ Bottom_Content = "XYZ" };
var iSitecoreContext = new Mock<Glass.Mapper.Sc.ISitecoreContext>();
iSitecoreContext.Setup(_ => _.GetCurrentItem<Home_Control>(false, false)).Returns(model);
HomeBottomContentController controllerUnderTest = new HomeBottomContentController(iSitecoreContext.Object);
var result = controllerUnderTest.IndexTest() as ViewResult;
}

TableControllers Unit test

So I'm trying to write a simple tablecontroller Unit test for my backend??
I havent been able to do so, all I've achieve is writing unit testing for ApiControllers but is there a way to write a Unit test for TableControllers?
What I'll like to do is this:
public class AuctionController : TableController<Auction>
{
protected override void Initialize(HttpControllerContext controllerContext)
{
base.Initialize(controllerContext);
MobileServiceContext context = new MobileServiceContext();
DomainManager = new EntityDomainManager<Auction>(context, Request);
}
// GET tables/Auction
public IQueryable<Auction> GetAllAuction()
{
return Query();
}
// GET tables/Auction/48D68C86-6EA6-4C25-AA33-223FC9A27959
public SingleResult<Auction> GetAuction(string id)
{
return Lookup(id);
}
// PATCH tables/Auction/48D68C86-6EA6-4C25-AA33-223FC9A27959
public Task<Auction> PatchAuction(string id, Delta<Auction> patch)
{
return UpdateAsync(id, patch);
}
// POST tables/Auction
public async Task<IHttpActionResult> PostAuction(Auction item)
{
Auction current = await InsertAsync(item);
return CreatedAtRoute("Tables", new { id = current.Id }, current);
}
// DELETE tables/Auction/48D68C86-6EA6-4C25-AA33-223FC9A27959
public Task DeleteAuction(string id)
{
return DeleteAsync(id);
}
}
and i wish to make a test controller like this one:
[TestClass]
public class AuctionControllerTests
{
private readonly AuctionController _controller;
public AuctionControllerTests()
{
_controller = new AuctionController();
}
[TestMethod]
public void Fetch_all_existing_items()
{
Assert.Equal(2, _controller.GetAllTodoItems().ToList().Count);
}
}
how can I possibly be able to get this to work??? Please I would appreciate your help a lot.
Yes. it is possible but you code is not unit testable. Here are the steps for you
Find a way inject your depedencies MobileServiceContext and DomainManager
You need to set up contexts and requests etc as in shown in the following code.
(Code assumes you are using Moq)
public class ControllerUnitTestBase<T> where T: Controller
{
private Action<RouteCollection> _routeRegistrar;
private Mock<HttpRequestBase> _mockRequest;
protected virtual Action<RouteCollection> RouteRegistrar
{
get { return _routeRegistrar ?? DefaultRouteRegistrar; }
set { _routeRegistrar = value; }
}
protected Mock<HttpRequestBase> MockRequest
{
get
{
if (_mockRequest == null)
{
_mockRequest = new Mock<HttpRequestBase>();
}
return _mockRequest;
}
}
public abstract T TargetController { get; }
protected void TargetSetup()
{
var routes = new RouteCollection();
RouteRegistrar(routes);
var responseMock = new Mock<HttpResponseBase>();
responseMock.Setup(x => x.ApplyAppPathModifier(It.IsAny<string>())).Returns((string url) => url);
var contextMock = new Mock<HttpContextBase>();
contextMock.SetupGet(x => x.Request).Returns(MockRequest.Object);
contextMock.SetupGet(x => x.Response).Returns(responseMock.Object);
contextMock.SetupGet(x => x.Session).Returns(Mock<HttpSessionStateBase>().Object);
TargetController.ControllerContext = new ControllerContext(contextMock.Object, new RouteData(), TargetController);
TargetController.Url = new UrlHelper(new RequestContext(contextMock.Object, new RouteData()), routes);
}
protected void DefaultRouteRegistrar(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
}
}
Inherit from this code and make sure you call TargetSetup() before test execution ( maybe in test initialization (setup). And you are good to go as in:
[TestClass]
public class AuctionControllerTests: TestControllerBase<AuctionController>
{
public AuctionController TargetController {
get {return new AuctionController();//inject your mocked dependencies}}
[TestInitialize]
public void SetUp()
{
TargetSetup()
}
}
So Thanks for the mocking solution, It worked but I wrote a generic better solution without using mocking framework, I'll apply mocking framework later, right now I'll stick with fakes and real dbs for integration tests.
but firstable I wrote a Generic TableController in order to apply multiple EntityData and DbContext for those who had more than one Context, also you could apply a FakeContext thanks to the abstraction of interfaces but i havent applied to this example.
First This is my BaseController:
//This is an abstract class so we can apply inheritance to scalfolded tablecontrollers<T>.
public abstract class BaseController<TModel, TDbContext> : TableController<TModel> where TModel : class, ITableData
where TDbContext:DbContext, new()
{
protected override void Initialize(HttpControllerContext controllerContext)
{
base.Initialize(controllerContext);
var context = new TDbContext();
SetDomainManager(new EntityDomainManager<TModel>(context, Request));
}
public void SetDomainManager(EntityDomainManager<TModel> domainManager)
{
DomainManager = domainManager;
}
}
this is my scalfolded controller with my basecontroller applied!!!
public class AuctionController : BaseController<Auction, MobileServiceContext>
{
public IQueryable<Auction> GetAllAuction()
{
return Query();
}
// GET tables/Auction/48D68C86-6EA6-4C25-AA33-223FC9A27959
public SingleResult<Auction> GetAuction(string id)
{
return Lookup(id);
}
// PATCH tables/Auction/48D68C86-6EA6-4C25-AA33-223FC9A27959
public Task<Auction> PatchAuction(string id, Delta<Auction> patch)
{
return UpdateAsync(id, patch);
}
// POST tables/Auction
public async Task<IHttpActionResult> PostAuction(Auction item)
{
Auction current = await InsertAsync(item);
return CreatedAtRoute("Tables", new { id = current.Id }, current);
}
// DELETE tables/Auction/48D68C86-6EA6-4C25-AA33-223FC9A27959
public Task DeleteAuction(string id)
{
return DeleteAsync(id);
}
}
With my generic application I can apply any DbContext that way you could even apply FakeDbContexts in order to avoid SqlConnection or Cloud connection such as Azure which is the one I used in this example.
UPDATED MARCH 14th, 2018
All this two library are on my Backend project, now I'll show you my test project in order to Unit Test a TableController
public abstract class ControllerTestBase<TController, TModel, TDbContext> where TController : BaseController<TModel, TDbContext>, new()
where TModel : class, ITableData
where TDbContext: DbContext, new()
{
protected readonly TController Controller;
protected ControllerTestBase()
{
Controller = new TController();
Controller.Configuration = new HttpConfiguration();
Controller.Request = new HttpRequestMessage();
var context = new TDbContext();
Controller.SetDomainManager(new EntityDomainManager<TModel>(context, Controller.Request));
}
}
Ok thanks to this abstract class you can supress the initialize setup from the testing library because each time you run a test it will call the generic test constructor, setting up all the necessary requierements and thus avoid ArgumentNullExceptions and InvalidOperationExceptions such common problem for unit testing tablecontroller since isnt quite intuitive to initialize as an ApiController.
Finally if you modify this then you can run a test like this:
[TestClass]
public class AuctionControllerTest : ControllerTestBase<AuctionController, Auction, MobileServiceContext>
{
[TestMethod]
public void Fetch_All_Existing_Items()
{
Assert.AreEqual(1, Controller.GetAllAuction().ToList().Count);
}
}
thanks to my generic application you can now use this code as an example to be apply to your TableControllers and also if you follow the Interface Segregation Principle you could apply FakeDbContext to your Controllers.
For those who helped me thanks you opened my mind into coming with this solution!!!

Categories

Resources