I am writting unit test cases. I am using nunit and rhino mock.
Method which is i am testing is
public ActionResult Details()
{
EmployeeDTO employee = this.EmployeeService.GetLoggedInEmployee();
EmployeeModel model = assembler.ToEmployeeModel(employee);
model.Title = GetEmployeeNameTitle(employee);
model.Controller = "LoanOfficer";
model.SelectedTab = MainNavTabs.LoanOfficerDetails;
return View(model);
}
And test case written is
[Test]
public void TestDetails()
{
EmployeeDTO employee = new EmployeeDTO();
EmployeeService.Stub(a => a.GetLoggedInEmployee()).Return(employee);
EmployeeModel model = new EmployeeModel{ Title = UtilityTests.Title, };
assembler.Stub(b => b.ToEmployeeModel(employee)).Return(model);
controller.Details();
// Assert
}
I have done
private ILoanModelAssembler loanAssembler;
loanAssembler = TestUtility.DynamicMock<ILoanModelAssembler>();
but still here model is null ? Is there is any way to correct it in test method?
It's null because your you're not taking control of the actual instance of EmployeeService from within your test. How is your EmployeeService dependency being added to the controller? Is it an interface? You would need it to be an interface so that Rhino Mocks can mock it and you would need to inject it into the constructor of your controller so that you can inject your mocked instance into your test. Something like this:
private IEmployeeService employeeService;
public EmployeeController(IEmployeeService employeeService)
{
this.employeeService = employeeService;
}
Then in your test you can say:
var employeeServiceStub = MockRepository.GenerateStub<IEmployeeService>();
var employee = new EmployeeDTO();
employeeServiceStub.Stub(a => a.GetLoggedInEmployee()).Return(employee);
Related
I am Making Mock of Register Agency User But It showing some of its attribute Null.
I am new and I don't understand this.
I am trying to make Mock of Register Agency User that is the model
[TestMethod]
public async Task ABCreateActionResult_ReturnsBadRequest_Badrequest()
{
RegisterAgencyUserRequest mock = new Mock<RegisterAgencyUserRequest>().Object;
var controller = _accountController.RegisterAgencyUser(mock);
JsonResult viewResult = (JsonResult)await _accountController.RegisterAgencyUser(mock);
}
Here is what I have to Test
public async Task<IActionResult> RegisterAgencyUser([FromBody] Models.Request.RegisterAgencyUserRequest request)
{
JsonContentResult jsonContentResult = new JsonContentResult();
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (string.IsNullOrEmpty(request.InvitationCode) || string.IsNullOrWhiteSpace(request.InvitationCode))
return Json(new SharedResponse(AppConstants.ServiceReponses.Error, "A user can't be registered without invitation"));
var invitationDetails = _inviteRepository.GetInvitaionCodeDetails(request.InvitationCode);
if (invitationDetails.Type != (int)InviteType.Agency)
{
return Json(new SharedResponse(AppConstants.ServiceReponses.Error, "Invalid invitation code"));
}
//...
You only mock dependencies to your class that you are testing. So you don't need to mock a POCO. Just set it up with dummy data like below:
var model = new RegisterAgencyUserRequest
{
Address = "Value1",
AgencyName = "Value2",
//...
};
and use it like below:
var controller = _accountController.RegisterAgencyUser(model);
Your dependency for the method is:
_inviteRepository.GetInvitaionCodeDetails()
so you need to mock the _inviteRepository and inject it into the subject controller under test when initializing.
You need to setup something on the mock, your code just creates an empty object.
var mock = new Mock<RegisterAgencyUserRequest>();
mock.Setup(x => x.Address).Returns(() => "some address");
RegisterAgencyUserRequest request = mock.Object;
Edit: The answer from Azhar Khorasany explains how it should be done, by not mocking the POCO, but the service/repository that you use in your test.
I'm implementing Unit Test on existing software.
These software is in ASP.NET MVC, and I want test the return of a Action, of a Controller.
But in this Action a I have the code:
public ActionResult EditProfile(
string accountId = null,
string partnership = null,
AccountType? subscriptionType = null,
bool forcePartnerUpdate = false)
{
var model = new EditProfileModel();
var account = _authUser.Account;
var catalogClient = new CatalogService.CatalogClient(Request.Cookies, Globals.CatalogURL);
The problem is because the last line : "new CatalogService.CatalogService()"
I'm using this class in other part of Action:
model.ListBrands = new List<Brands>();
model.ListAvailableBrands = new List<Brands>();
model.ListSubscribedBrands = new List<Brands>();
var brands = catalogClient.GetBrandsWithManufacturer();
So, How I can mock this for tests?
I have thought in abstract for a interface and send how a parameter in action, but I don't have the Request in my NInjectModule to IoC and in other codes this class has other parameters, so I think I can't do IoC.
How I can mock this with moq?
Thank you for help.
I've thought and tested a lot and now I got to do the mock for my tests.
First, I've created a "Factory" to my class:
public interface ICatalogClientFactory
{
ICatalogClient Create(HttpCookieCollection cookies, string catalogUrl);
}
public class CatalogClientFactory : ICatalogClientFactory
{
public ICatalogClient Create(HttpCookieCollection cookies, string catalogUrl)
{
return new CatalogClient(cookies, catalogUrl);
}
}
Than, this Interface I've registered in the NinjectModule and set this in the constructor of Controller. So, I'm calling in my actions with this code:
ICatalogClientFactory _catalogClientFactory = catalogClientFactory;
var clientCatalog = _catalogClientFactory.Create(Request.Cookies, Globals.CatalogURL);
Now, I can mock "ICatalogClientFactory" and "ICatalogClient" to use in unit tests.
I'm having a difficult time trying to understand how to appropriately return mocked data from a simulated database call in a unit test.
Here's an example method I want to unit test (GetBuildings):
public class BuildingService : IBuildingService {
public IQueryable<Building> GetBuildings(int propertyId)
{
IQueryable<Building> buildings;
// Execution path for potential exception thrown
// if (...) throw new SpecialException();
// Another execution path...
// if (...) ...
using (var context = DataContext.Instance())
{
var Params = new List<SqlParameter>
{
new SqlParameter("#PropertyId", propertyId)
};
// I need to return mocked data here...
buildings = context
.ExecuteQuery<Building>(System.Data.CommandType.StoredProcedure, "dbo.Building_List", Params.ToArray<object>())
.AsQueryable();
}
return buildings;
}
}
So GetBuildings calls a stored procedure.
So I need to mock the DataContext, that of which I can override and set a testable instance. So what happens here is, in the above example DataContext.Instance() does return the mocked object.
[TestFixture]
public class BuildingServiceTests
{
private Mock<IDataContext> _mockDataContext;
[SetUp]
public void Setup() {
_mockDataContext = new Mock<IDataContext>();
}
[TearDown]
public void TearDown() {
...
}
[Test]
public void SomeTestName() {
_mockDataContext.Setup(r =>
r.ExecuteQuery<Building>(CommandType.StoredProcedure, "someSproc"))
.Returns(new List<Building>() { new Building() { BuildingId = 1, Title = "1" }}.AsQueryable());
DataContext.SetTestableInstance(_mockDataContext.Object);
var builings = BuildingService.GetBuildings(1, 1);
// Assert...
}
Please ignore some of the parameters, like propertyId. I've stripped those out and simplified this all. I simply can't get the ExecuteQuery method to return any data.
All other simple peta-poco type methods I can mock without issue (i.e. Get, Insert, Delete).
Update
DataContext.Instance returns the active instance of the DataContext class, if exists, and if not exists, returns a new one. So the method of test under question returns the mocked instance.
Do not mock DataContext. Because mocking DataContext will produce tests tightly coupled to the implementation details of DataContext. And you will be forced to change tests for every change in the code even behavior will remain same.
Instead introduce a "DataService" interface and mock it in the tests for BuildingService.
public interface IDataService
{
IEnumerable<Building> GetBuildings(int propertyId)
}
Then, you can tests implementation of IDataService agains real database as part of integration tests or tests it agains database in memory.
If you can test with "InMemory" database (EF Core or Sqlite) - then even better -> write tests for BuildingService against actual implementation of DataContext.
In tests you should mock only external resources (web service, file system or database) or only resources which makes tests slow.
Not mocking other dependencies will save you time and give freedom while you refactoring your codebase.
After update:
Based on the updated question, where BuildingService have some execution path - you can still testing BuildingService and abstract data related logic to the IDataService.
For example below is BuildingService class
public class BuildingService
{
private readonly IDataService _dataService;
public BuildingService(IDataService dataService)
{
_dataService = dataService;
}
public IEnumerable<Building> GetBuildings(int propertyId)
{
if (propertyId < 0)
{
throw new ArgumentException("Negative id not allowed");
}
if (propertyId == 0)
{
return Enumerable.Empty<Building>();
}
return _myDataService.GetBuildingsOfProperty(int propertyId);
}
}
In tests you will create a mock for IDataService and pass it to the constructor of BuildingService
var fakeDataService = new Mock<IDataContext>();
var serviceUnderTest = new BuildingService(fakeDataService);
Then you will have tests for:
"Should throw exception when property Id is negative"
"Should return empty collection when property Id equals zero"
"Should return collection of expected buildings when valid property Id is given"
For last test case you will mock IDataService to return expected building only when correct propertyId is given to _dataService.GetBuildingsOfProperty method
In order for the mock to return data is needs to be set up to behave as expected given a provided input.
currently in the method under test it is being called like this
buildings = context
.ExecuteQuery<Building>(System.Data.CommandType.StoredProcedure, "dbo.Building_List", Params.ToArray<object>())
.AsQueryable();
Yet in the test the mock context is being setup like
_mockDataContext.Setup(r =>
r.ExecuteQuery<Building>(CommandType.StoredProcedure, "someSproc"))
.Returns(new List<Building>() { new Building() { BuildingId = 1, Title = "1" }}.AsQueryable());
Note what the mock is told to expect as parameters.
The mock will only behave as expected when provided with those parameters. Otherwise it will return null.
Consider the following example of how the test can be exercised based on the code provided in the original question.
[Test]
public void SomeTestName() {
//Arrange
var expected = new List<Building>() { new Building() { BuildingId = 1, Title = "1" }}.AsQueryable();
_mockDataContext
.Setup(_ => _.ExecuteQuery<Building>(CommandType.StoredProcedure, It.IsAny<string>(), It.IsAny<object[]>()))
.Returns(expected);
DataContext.SetTestableInstance(_mockDataContext.Object);
var subject = new BuildingService();
//Act
var actual = subject.GetBuildings(1);
// Assert...
CollectionAssert.AreEquivalent(expected, actual);
}
That said, the current design of the system under test is tightly coupled to a static dependency which is a code smell and makes the current design follow some bad practices.
The static DataContext which is currently being used as a factory should be refactored as such,
public interface IDataContextFactory {
IDataContext CreateInstance();
}
and explicitly injected into dependent classes instead of calling the static factory method
public class BuildingService : IBuildingService {
private readonly IDataContextFactory factory;
public BuildingService(IDataContextFactory factory) {
this.factory = factory
}
public IQueryable<Building> GetBuildings(int propertyId) {
IQueryable<Building> buildings;
using (var context = factory.CreateInstance()) {
var Params = new List<SqlParameter> {
new SqlParameter("#PropertyId", propertyId)
};
buildings = context
.ExecuteQuery<Building>(System.Data.CommandType.StoredProcedure, "dbo.Building_List", Params.ToArray<object>())
.AsQueryable();
}
return buildings;
}
}
This will allow for a proper mock to be created in injected into the subject under test without using a static workaround hack.
[Test]
public void SomeTestName() {
//Arrange
var expected = new List<Building>() { new Building() { BuildingId = 1, Title = "1" }}.AsQueryable();
_mockDataContext
.Setup(_ => _.ExecuteQuery<Building>(CommandType.StoredProcedure, It.IsAny<string>(), It.IsAny<object[]>()))
.Returns(expected);
var factoryMock = new Mock<IDataContextFactory>();
factoryMock
.Setup(_ => _.CreateInstance())
.Returns(_mockDataContext.Object);
var subject = new BuildingService(factoryMock.Object);
//Act
var actual = subject.GetBuildings(1);
// Assert...
CollectionAssert.AreEquivalent(expected, actual);
}
public List<CustomerViewModel> GetResellerCustomersWithProperties(string shortCode)
{
var businessManager = DependencyContainer.GetInstance<ICortexBusinessManager>();
return businessManager.GetResellerCustomersWithProperties(shortCode);
}
How do we write Test case using Nunit which has a dependency from interfaces.
Dependency Injection is your friend here.
Note You will need an IOC container, such as Autofac, Unity, StructureMap etc... wired up with your application.
Inject your dependencies in the constructor of your class:
public class CustomerService
{
private ICortexBusinessManager _cortexBusinessManager;
public CustomerService (ICortexBusinessManager cortexBusinessManager)
{
_cortexBusinessManager = cortexBusinessManager;
}
public List<CustomerViewModel> GetResellerCustomersWithProperties(string shortCode)
{
return _cortexBusinessManager.GetResellerCustomersWithProperties(shortCode);
}
}
You can then use a mocking framework within your unit test to mock calls to your interface.
Example below uses Moq
public class CustomerServiceTest
{
[Test]
public void GetResellerCustomersWithProperties_ReturnsFromCortextBusinessManager()
{
//arrange
var mockCortexBusinessManager = new Mock<ICortexBusinessManager>();
//if GetResellerCustomersWithProperties is called with s123, return a new list of CustomerViewModel
//with one item in, with id of 1
mockCortexBusinessManager.Setup(m=> m.GetResellerCustomersWithProperties("s123"))
.Returns(new List<CustomerViewModel>(){new CustomerViewModel{Id = 1}});
var customerService = new CustomerService(mockCortexBusinessManager.Object);
//act
var result = customerService.GetResellerCustomersWithProperties("s123");
//assert
Assert.AreEqual(1, result.Count())
Assert.AreEqual(1, result.FirstOrDefault().Id)
}
}
I have a controller called PostsController
public class PostsController : Controller
{
private readonly IPostsRepository repository;
public PostsController(IPostsRepository repository)
{
this.repository = repository;
}
public ViewResult Index()
{
var posts =
repository.All()
.OrderBy(post => post.PublishedAt);
return View("Index", posts.MapTo<PostViewModel>());
}
}
And a corresponding test fixture called PostsControllerTest
[TestFixture]
public class PostsControllerTest
{
private PostsController controller;
private Mock<IPostsRepository> repository;
[SetUp]
public void SetUp()
{
AutoMapperConfig.Configure();
repository = new Mock<IPostsRepository>();
controller = new PostsController(repository.Object);
}
[Test]
public void Index_ReturnsCorrectModel()
{
var actual = controller.Index().Model;
Assert.IsAssignableFrom<IEnumerable<PostViewModel>>(actual);
}
}
At the moment I am only testing that the controller returns the correct model type. Should I also stub the repository and test that the correct data is returned like this:
[Test]
public void Index_ReturnsCorrectModel()
{
var post = new Post
{
Slug = "continuing-to-an-outer-loop",
Title = "Continuing to an outer loop",
Summary = "When you have a nested loop, sometimes",
Content = "When you have a nested loop, sometimes",
PublishedAt = DateTime.Now.AddDays(7),
Tags = new Collection<Tag> { new Tag { Name = "Programming" } }
};
repository.Setup(repo => repo.All()).Returns(new[] { post });
var actual = controller.Index().Model as IEnumerable<PostViewModel>;
Assert.NotNull(actual);
Assert.AreEqual(1, actual.Count());
Assert.AreEqual(post.Title, actual.First().Title);
}
I feel so frustrated not knowing if I am unit testing properly. A clear explanation of which I approach I should take why would be very helpful.
I don't think you need to test the functionality of IPostRepository in this unit test. You should create a seperate unit test class for it.
Similarly the functionality of the MapTo<T> should be tested separately.
Unit tests should only test the functionality of the SUT (System Under Test) which in this case is the Index method of your PostsController class.
This is a simple method so the 2 things you want to be verifying in this unit test are:
1- The repository.All() method gets called once
2- Your view model is mapped correctly (which you are already doing)
This is how I would unit test this method:
[Test]
public void Index_ReturnsCorrectModel()
{
// Arrange
repository.Setup(repo => repo.All()).Returns(Enumerable.Empty<Post>());
// Act
var actual = controller.Index().Model;
// Assert
Assert.IsAssignableFrom<IEnumerable<PostViewModel>>(actual);
repository.Verify(repo => repo.All(), Times.Once);
}
Also, to minimize the effort required to arrange your unit test, use can use a library like AutoFixture which will automatically create the post object for you.