I am trying to setup like this:
[Test]
public void Observatoins_Were_Returned()
{
using (var mock = AutoMock.GetLoose())
{
// Arrange
mock.Mock<IRepository<WspObservation>>()
.Setup(x => x.GetAll())
.Returns(_observations);
var sut = mock.Create<CommonServices>();
WspResponse wspResponse;
// Act
var wspObservations = sut.GetAllObservations(out wspResponse);
var expectedErrorCode = ResponseCodes.SUCCESS;
// Assert
// Assert.AreEqual(expectedErrorCode, wspResponse.ResponseCode);
}
}
but when GetAllObservations() function is called it returns null in the actual code.
In the actual code IRepository is dependency injected which is working fine.
object that is being returned looks like this.
var _observations = new List<WspObservation>();
_observations.Add(new WspObservation() { DeviceName = "Devcie One", Steps = "3000" });
_observations.Add(new WspObservation() { DeviceName = "Devcie One", Steps = "2000" });
the actual function that is being tested looks like this
public List<WspObservation> GetAllObservations(out WspResponse getAllWspObservationsResponse)
{
List<WspObservation> allWspObservations = new List<WspObservation>();
getAllWspObservationsResponse = new WspResponse();
try
{
//some other Business Logic
allWspObservations = _wspObsrep.GetAll().ToList();
//some other Business Logic
}
catch (Exception ex)
{
getAllWspObservationsResponse.ResponseCode = ResponseCodes.DatabaseGetError;
}
return allWspObservations;
}
dependency injection looks like this
private IRepository<WspObservation> _wspObsrep;
public CommonServices(IRepository<WspObservation> wspObsrep)
{
_wspObsrep = wspObsrep;
}
What is the intention of
var sut = mock.Create<CommonServices>();
Isn't it better to Create the real SUT object and inject the IRepository mock?
I would do it this way:
var repoMock = mock.Mock<IRepository<WspObservation>>()
.Setup(x => x.GetAll())
.Returns(_observations);
var sut = new CommonServices(repoMock);
Related
I have a method:
public class WorkerClass : IWorkerClass
{
private int myworkId = 0;
public void Workflow(int theWorkid)
{
var aTask = new Task(() =>
{
this.myworkId = theWorkid;
//Some calculations
});
aTask.Start();
}
}
I have a Unit test method :
[DataTestMethod]
[DataRow(23)]
public class workerTester
{
public void WorkflowTest(int theWorkflowMode)
{
// Arrange
var aWorkTester = new Mock<IWorkerClass>();
var aExpectedWorkflowMode = 23;
myWorkerPrivateObj = new PrivateObject(aWorkTester);
// Act
myWorkerPrivateObj .Invoke("Workflow", theWorkflowMode);
// Assert
//Thread.Sleep(1000); If i uncomment it works
var aActualWorkflowModeType = myWorkerPrivateObj.GetField("myworkId");
Assert.AreEqual(aExpectedWorkflowModeType, aActualWorkflowModeType);
}
}
If i uncomment Thread.Sleep(1000), aActualWorkflowModeType comes as 23. But if i comment it aActualWorkflowModeType comes as 0. I am assuming my assert is called before my task is complete.
How can i wait until task is complete in my Unit test?
I figured out a way to do it for unit testing:
var lookupTask = Task<WorkerClass>.Factory.StartNew(() =>
{
return new WorkerClass();
});
lookupTask.Wait();
So my new Unit test method looks like this :
[DataTestMethod]
[DataRow(23)]
public class workerTester
{
public void WorkflowTest(int theWorkflowMode)
{
// Arrange
var aWorkTester = new Mock<IWorkerClass>();
var aExpectedWorkflowMode = 23;
myWorkerPrivateObj = new PrivateObject(aWorkTester);
// Act
myWorkerPrivateObj .Invoke("Workflow", theWorkflowMode);
var lookupTask = Task<WorkerClass>.Factory.StartNew(() =>
{
return new WorkerClass();
});
// Assert
lookupTask.Wait();
var aActualWorkflowModeType = myWorkerPrivateObj.GetField("myworkId");
Assert.AreEqual(aExpectedWorkflowModeType, aActualWorkflowModeType);
}
}
This seems to work
I used test as below. I have one big method for initialize whole dbcontext (it is larger than pasted below, it is similar, but with more models and acces to each dbsets for MoQ Verify) something like fake db. Next I inject it to service and call method that using it.
Is it correct way for testing services (that using dbcontext) with unit tests? And if it is not correct, what is good way for testing services like this (maybe only write test that connect to real db)?
My Test:
[Test]
public void ExampleServiceTest()
{
var mock = InitializeMockContext();
var service = new TagsService(mock.Object);
var result = service.GetTags(2);
var expectection = 2;
Assert.AreEqual(expectection, result.Id);
}
Method that create mocked DBContext:
public Mock<MyDBContext> InitializeMockContext()
{
var mock = new Mock<MyDBContext>();
var mockDataTags = new List<Tags> {
new Tags { Id = 1, Count = 3 },
new Tags { Id = 2, Count = 2} }.AsQueryable();
var mockSet = new Mock<DbSet<Tags>>();
mockSet.As<IQueryable<Tags>>().Setup(m => m.Provider).Returns(mockDataTags.Provider);
mockSet.As<IQueryable<Tags>>().Setup(m => m.Expression).Returns(mockDataTags.Expression);
mockSet.As<IQueryable<Tags>>().Setup(m => m.ElementType).Returns(mockDataTags.ElementType);
mockSet.As<IQueryable<Tags>>().Setup(m => m.GetEnumerator()).Returns(mockDataTags.GetEnumerator());
mock.Setup(x => x.Tags).Returns(mockSet.Object);
//I have more than just one model here
return mock;
}
MyService:
public class TagsService
{
private readonly MyDBContext _ctx;
public TagsService(MyDBContext ctx)
{
_ctx = ctx;
}
public Tags GetTags(int count)
{
using (var db = _ctx)
{
return db.Tags.First(x => x.Count == count);
}
}
}
I'm writing mock test cases for SignalR application. I just started with the help of Unit Testing SignalR Applications, but my requirement is little bit different that example shown there.
Following is the code I have done after googling.
SignalRHub
public class HubServer : Hub
{
[HubMethodName("SendNofication")]
public void GetNofication(string message)
{
try
{
Clients.Group("Manager").BroadCast(message);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
Unit Test
public interface IClientContract { }
[TestMethod]
public void GetNoficationTest()
{
var hub = new HubServer();
var mockClients = new Mock<IHubCallerConnectionContext<dynamic>>();
hub.Clients = mockClients.Object;
var all = new Mock<IClientContract>();
string message = "Message to send";
mockClients.Setup(m => m.Group("Manager")).Returns(message);
mockClients.Setup(m => m.All).Returns(all.Object);
hub.GetNofication("Mock call to SingalR hub");
all.VerifyAll();
}
I'm beginner in Unit Test application, just want to confirm if this is right way to mock SignalR Groups.
Using examples from Microsoft.AspNet.SignalR.Tests
Hubs Group Are Mockable
The client contract needs to be updated with the necessary methods. In this case you will have to add Broadcast method to match how it is called in the Hub
public interface IClientContract {
void Broadcast(string message);
}
Next arrange the test by setting up the dependencies for the hub and exercise the method under test.
[TestMethod]
public void _GetNoficationTest() {
// Arrange.
var hub = new HubServer();
var mockClients = new Mock<IHubCallerConnectionContext<dynamic>>();
var groups = new Mock<IClientContract>();
var message = "Message to send";
var groupName = "Manager";
hub.Clients = mockClients.Object;
groups.Setup(_ => _.Broadcast(message)).Verifiable();
mockClients.Setup(_ => _.Group(groupName)).Returns(groups.Object);
// Act.
hub.GetNofication(message);
// Assert.
groups.VerifyAll();
}
Another option would be to fake the group using an ExpandoObject given that Clients.Group in this instance returns dynamic
[TestMethod]
public void _GetNoficationTest_Expando() {
// Act.
var hub = new HubServer();
var mockClients = new Mock<IHubCallerConnectionContext<dynamic>>();
dynamic groups = new ExpandoObject();
var expected = "Message to send";
string actual = null;
var groupName = "Manager";
bool messageSent = false;
hub.Clients = mockClients.Object;
groups.Broadcast = new Action<string>(m => {
actual = m;
messageSent = true;
});
mockClients.Setup(_ => _.Group(groupName)).Returns((ExpandoObject)groups);
// Act.
hub.GetNofication(expected);
// Assert.
Assert.IsTrue(messageSent);
Assert.AreEqual(expected, actual);
}
This is my first post!
I'm trying to write a unit test using nsubstitute but I'm finding the last bit difficult.
I've included a snippet of code below, the test fails when calling the method on the model. Is it possible to stub this method out? Similar to if it was an interface
Cheers guys! Look forward to your responses
James
My unit test attempt
public class MyTests
{
private IModelMapper _modelMapper;
[SetUp]
public void Setup()
{
_modelMapper = Substitute.For<IModelMapper>();
}
[Test]
public void GetModel_Returns_A_Model()
{
var result = theClass.GetModel(new Booking {CurrencyCode = ""}, null);
**UPDATE to include assert**
// Assert
Assert.IsInstance<BasketModel>(result);
}
}
Feature code
public Model GetModel(Booking booking)
{
var model = _modelMapper.Map(booking);
// Is it possible to stub this out? Similar to if it was an interface
model.FormatPricing(somethingHere);
return model;
}
UPDATE - to illustrate return type
BasketModel model = _modelMapper.Map(booking);
UPDATE #2 - to include return
var basketModel = new BasketModel();
BasketModel model = _modelMapper.Map(booking).Returns(basketModel);
Can you include what test failure message you're getting?
Here is the general approach I tend to take for this kind of code. Say we're injecting the IModelMapper into the class-under-test (approximate code; I haven't tested):
[SetUp]
public void Setup()
{
_modelMapper = Substitute.For<IModelMapper>();
theClass = new TheClass(_modelMapper);
}
[Test]
public void GetModel_Returns_Model_From_Mapper()
{
// Arrange
var booking = new Booking { CurrencyCode = "" };
var expectedModel = new BasketModel();
_modelMapper.GetModel(booking).Returns(expectedModel);
// Act
var result = theClass.GetModel(booking, null);
// Assert
Assert.AreSame(expectedModel, result);
}
If you want to stub out BasketModel.FormatModel (that's a big "if". I would recommend using the real type if possible) then you'll want to substitute for BasketModel too.
Be careful - NSubstitute will not work with non-virtual methods, so you may want an interface for BasketModel, or just make sure to use virtual everywhere. (Again, untested code ahead)
[Test]
public void ModelReturnedShouldBeFormatted()
{
// Arrange
var booking = new Booking { CurrencyCode = "" };
var expectedModel = Substitute.For<IBasketModel>();
_modelMapper.GetModel(booking).Returns(expectedModel);
// Act
var result = theClass.GetModel(booking, null);
// Assert
expectedModel.Received().FormatModel(Arg.Any<SomethingHere>());
}
This is testing adherence to a particular contract - TheClass will call FormatModel on the BasketModel returned from the mapper. If you need to duplicate some implementation in the test (again, this is generally discouraged), you can use When..Do:
[Test]
public void FormatModel()
{
// Arrange
var booking = new Booking { CurrencyCode = "" };
var expectedModel = Substitute.For<IBasketModel>();
expectedModel
.When(x => x.FormatModel(Arg.Any<SomethingHere>()))
.Do(/* some action */);
_modelMapper.GetModel(booking).Returns(expectedModel);
// Act
var result = theClass.GetModel(booking, null);
// Assert
// assertion here that depends on "some action" and result
}
Hope this helps.
This is my Domain class
public partial class Department
{
public int DepartmentId { get; set; }
[Required]
public string DepartmentCode { get; set; }
[Required]
public string DepartmentFullName { get; set; }
public bool Status { get; set; }
public System.DateTime CreatedOn { get; set; }
}
In my MVC application, this is how my DepartmentService class looks like.
public class DepartmentService : IDepartmentService
{
private IUnitOfWork _UoW;
private IRepository<Department> repository;
public DepartmentService(IUnitOfWork UoW)
{
_UoW = UoW;
repository = _UoW.GetRepository<Department>();
}
public IList<Department> GetAllDepartments()
{
return repository.GetAll();
}
public bool SaveDepartment(Department newDepartment)
{
try
{
repository.Add(newDepartment);
_UoW.Save();
}
catch (Exception)
{
throw;
}
return true;
}
}
I wrote one unit test for GetAllDepartments methods as below.
[Test]
public void When_GetAllDepartments_Is_Called_RepositoryGetAll_ShouldBeCalled()
{
// Arrange
var mockUnitOfWork = new Mock<IUnitOfWork>();
var mockRepository = new Mock<IRepository<Department>>();
mockUnitOfWork.Setup(x => x.GetRepository<Department>())
.Returns(mockRepository.Object);
var sut = new DepartmentService(mockUnitOfWork.Object);
// Act
sut.GetAllDepartments();
// Assert
mockRepository.Verify(x => x.GetAll());
}
I want to test the SaveDepartment method where, when department is saved successfully, it should return true. I am not able to write unit test for this.
I also want to test when DepartmentCode or DepartmentFullName is blank and if Save is attempted, an exception should be thrown.
This is what i have so far.
[Test]
public void ShouldSucessfully_SaveNewDepartment()
{
// Arrange
var mockUnitOfWork = new Mock<IUnitOfWork>();
var mockRepository = new Mock<IRepository<Department>>();
Department newDept = new Department {
CreatedOn = DateTime.Now,
Status = true,
DepartmentFullName = "DFN",
DepartmentCode = "DC" };
mockUnitOfWork.Setup(x => x.GetRepository<Department>())
.Returns(mockRepository.Object);
var sut = new DepartmentService(mockUnitOfWork.Object);
// Act
sut.SaveDepartment(newDept);
// Assert
// ???
}
First of all - move all common arrange code to SetUp method:
private Mock<IUnitOfWork> mockUnitOfWork;
private Mock<IRepository<Department>> mockRepository;
private DepartmentService sut;
[SetUp]
public void SetUp()
{
mockUnitOfWork = new Mock<IUnitOfWork>();
mockRepository = new Mock<IRepository<Department>>();
mockUnitOfWork.Setup(x => x.GetRepository<Department>())
.Returns(mockRepository.Object);
sut = new DepartmentService(mockUnitOfWork.Object);
}
// tests will be here
That will make tests much easier to read and maintain. Next - do not stick to implementation when naming your tests:
When_GetAllDepartments_Is_Called_RepositoryGetAll_ShouldBeCalled
What if you will rename repository method to FindAll? What if service method will be renamed? Test becomes obsolete. And nobody will know about that. You should describe WHAT your SUT should do instead of HOW:
[Test]
public void ShouldGetAllDepartments()
{
var expected = new List<Department>{ CreateDepartment(), CreateDepartment()};
mockRepository.Setup(r => r.GetAll()).Returns(expected);
var actual = sut.GetAllDepartments();
Assert.That(actual, Is.EqualTo(expected));
mockRepository.VerifyAll();
}
As you can see, test name changed. Also I verify different things here - not only repository was called (that check can be removed actually), but that service returns exactly same departments which it gets from repository. Thats what service does. And second test:
[Test]
public void ShouldSucessfullySaveNewDepartment()
{
var department = CreateDepartment();
mockRepository.Setup(r => r.Add(department));
var result = sut.SaveDepartment(department);
Assert.True(result);
mockRepository.VerifyAll();
mockUnitOfWork.Verify(u => u.Save());
}
It verifies following service behavior: service should pass to repository exactly same department instance which was passed to service, and it should return true, it also calls save on unit of work to submit data.
BTW As you can see above I use helper method to make tests more clean:
private Department CreateDepartment()
{
return new Department {
CreatedOn = DateTime.Now,
Status = true,
DepartmentFullName = "DFN",
DepartmentCode = "DC"
};
}
And bonus - verifying that service does not saves department which already exists:
[Test]
public void ShouldNotSaveExistingDepartment()
{
mockUnitOfWork.Setup(u => u.Save()).Throws<NonUniqueEntityException>();
var result = sut.SaveDepartment(CreateDepartment());
Assert.False(result);
mockUnitOfWork.VerifyAll();
}
As you can see, expected behavior is simple - when unit of work throws NonUniqueEntityException during department saving, service should return false. Yes, I think it's better to return false. Here is service code which makes this test pass:
public bool SaveDepartment(Department department)
{
try
{
repository.Add(department);
_UoW.Save();
return true;
}
catch (NonUniqueEntityException e)
{
// log exception
return false;
}
}
First of all remove the redundant try...catch.
There's no point in catching an exception just to rethrow it.
As far as the test you asked for here is the snippet:
[Test]
public void ShouldSucessfully_SaveNewDepartment()
{
// Arrange
var mockUnitOfWork = new Mock<IUnitOfWork>();
var mockRepository = new Mock<IRepository<Department>>();
Department newDept = new Department { CreatedOn = DateTime.Now, Status = true, DepartmentFullName = "DFN", DepartmentCode = "DC" };
mockUnitOfWork.Setup(x => x.GetRepository<Department>()).Returns(mockRepository.Object);
var sut = new DepartmentService(mockUnitOfWork.Object);
// Act
bool result = sut.SaveDepartment(newDept);
// Assert
Assert.That(result, Is.True);
}
[Test]
public void ShouldThrowExceptionWhenExceptionThrownInternally_SaveNewDepartment()
{
// Arrange
var mockUnitOfWork = new Mock<IUnitOfWork>();
var mockRepository = new Mock<IRepository<Department>>();
mockUnitOfWork.Setup(x => x.GetRepository<Department>()).Returns(mockRepository.Object);
mockUnitOfWork.Setup(uow => uow.Save()).Throws<Exception>();
var sut = new DepartmentService(mockUnitOfWork.Object);
// Act
TestDelegate action = () => sut.SaveDepartment(new Department());
// Assert
Assert.Throws<Exception>(action);
}
I also want to test when DepartmentCode or DepartmentFullName is blank and if Save is attempted, an exception should be thrown.
It depend on who you expect to check for those values: if you want to rely on you database or unitofwork to check for those fields this is not the fixture to test for specific failure conditions it you want a unit test. Here you should only test what happens in case uow throws exception.
If you plan to add those check in the department service than you can do the following:
[Test]
public void ShouldThrowExceptionWhenDepartmentCodeIsNull_SaveNewDepartment()
{
// Arrange
var mockUnitOfWork = new Mock<IUnitOfWork>();
Department newDept = new Department
{
CreatedOn = DateTime.Now,
Status = true, DepartmentFullName = "DFN",
DepartmentCode = null
};
var sut = new DepartmentService(mockUnitOfWork.Object);
// Act
TestDelegate action = () => sut.SaveDepartment(newDept);
// Assert
Assert.Throws<ArgumentException>(action);
}
provided that you modified your method as follows:
public bool SaveDepartment(Department newDepartment)
{
if (string.IsNullOrEmpty(newDepartment.DepartmentCode))
{
throw new ArgumentException("DepartmentCode must be not null");
}
repository.Add(newDepartment);
_UoW.Save();
return true;
}