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);
}
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 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);
I am trying to mock a delegate, using Moq, but so far everything im doing is in vain.
I have made a small example of how the setup is:
1.A proxy class is abstracting a WCF service
public interface IServiceProxy
{
void FooService(ServiceProxy.FooServiceDelegate service);
}
public class ServiceProxy : IServiceProxy
{
private readonly EndpointAddress _fooServiceEndpoint;
public ServiceProxy(IConfiguration configuration)
{
_fooServiceEndpoint = new EndpointAddress(new Uri(configuration.WcfServiceEndpoint));
}
public delegate void FooServiceDelegate(IFooBar proxy);
public void FooService(FooServiceDelegate service)
{
Do<IFooBar>((service.Invoke), _fooServiceEndpoint);
}
private void Do<T>(UseServiceDelegate<T> f, EndpointAddress address)
{
UsingService<T>.Use(f.Invoke, address);
}
}
2.The service definition
/// <summary>
/// This is the interface the WCF service exposes
/// </summary>
public interface IFooBar
{
string Hello(string name);
}
3.And the class that uses the proxy
public class DoFoo
{
private readonly IServiceProxy _serviceProxy;
public DoFoo(IServiceProxy serviceProxy)
{
_serviceProxy = serviceProxy;
}
public string SayHello(string name)
{
var response = string.Empty;
_serviceProxy.FooService(proxy => { response = proxy.Hello(name); });
return response;
}
}
I would like to test that the methods defined on the delegate FooServiceDelegate with the input IFooBar is in fact called and also i would like to be able to mock the responce from a methodcall on a IFooBar via the delegate.
So far my attempts has been in vain, so i hope that there are some moq experts that can help here.
Here is an example of a test, that of course does not work as it is now.
[TestClass()]
public class DoFooTests
{
[TestMethod, TestCategory("Unit")]
public void SayHelloJohn_ShouldUseServiceProxy()
{//SETUP
var serviceMock = new Mock<IFooBar>(MockBehavior.Loose);
var delegateMock = new Mock<ServiceProxy.FooServiceDelegate>(MockBehavior.Strict);
var serviceProxyMock = new Mock<IServiceProxy>(MockBehavior.Strict);
serviceProxyMock.Setup(m => m.FooService(delegateMock.Object));
var name = "John";
var response = $"Hello {name}";
//Im trying something like this (of course this does not work...)
delegateMock.Setup(m => m.Hello(name)).Returns(response);
//EXECUTE
var doFoo = new DoFoo(serviceProxyMock.Object);
var result = doFoo.SayHello(name);
//ASSERT
// Do some assertions here....
}
}
You have to call the delegate when FooService is executed:
[TestMethod]
public void SayHelloJohn_ShouldUseServiceProxy()
{
const string EXPECTED_RESULT = "Hello John";
const string NAME = "John";
var fakeServiceProxy = new Mock<IServiceProxy>(MockBehavior.Strict);
var fakeFooBar = new Mock<IFooBar>(MockBehavior.Loose);
fakeFooBar.Setup(bar => bar.Hello(NAME)).Returns(EXPECTED_RESULT);
fakeServiceProxy.Setup(proxy => proxy.FooService(
It.IsAny<ServiceProxy.FooServiceDelegate>()))
.Callback<ServiceProxy.FooServiceDelegate>(arg => arg(fakeFooBar.Object));
var target = new DoFoo(fakeServiceProxy.Object);
var result = target.SayHello(NAME);
Assert.AreEqual(EXPECTED_RESULT, result);
}
The above snippet execute proxy => { response = proxy.Hello(name); }) when you call SayHello method.
enter code hereI have following method where i need to write unit test case to test this method.
public void ProcessDormantApplications()
{
List<long> dormantApplicationIDs = new List<long>();
dormantApplicationIDs = service.GetDormantApplications();
if (dormantApplicationIDs.Count > 0)
{
foreach (long dormantID in dormantApplicationIDs)
{
string msg = service.UpdateDormantApplications(dormantID);
}
}
}
}
and this is the TEST method i wrote.
[TestClass]
public class DormantApplicationsTest
{
ILogger logger;
IService Service;
[TestInitialize]
public void SetUp()
{
logger = MockRepository.GenerateStub<ILogger>();
Service = MockRepository.GenerateStub<IService>();
}
[TestMethod]
public void TESTProcessDormantApplications()
{
////arrange
////act
var target = new BLogic(service, logger);
target.ProcessDormantApplications();
////assert
// service.AssertWasCalled(x => x.
}
}
The actual method calls another service layer which inturn invokes web service to get data. In this scenario I am not sure what to ASSERT in this situation.
[TestMethod]
public void CheckProcessDormantApplications_InBetweenApplicationFailedToUpdate()
{
////arrange
var applicationIds = new List<long>()
{
1,2,3
};
UpdateResponse.isSuccess = true;
UpdateResponse.errorMessage = string.Empty;
Service.Stub(x => x.GetDormantApplications()).Return(applicationIds);
for(int i=0; i <= applicationIds.Count-1; i++)
{
if (i == 1) //set this application id response to FALSE so it should continnue with next record as well
{
UpdateResponse.isSuccess = false;
UpdateResponse.errorMessage = "making it fail for test";
}
Service.Stub(x =>x.UpdateDormantApplications(applicationIds[i])).Return(UpdateResponse);
}
////act
var target = new BLogic(Service, logger);
target.ProcessDormantApplications();
////assert
foreach (long id in applicationIds)
{
Service.AssertWasCalled(x => x.UpdateDormantApplications(id));
}
}
}
Based on the code you provide you have to set a behavior on GetDormantApplications which return some ids, then verify that UpdateDormantApplications was called for each id:
[TestMethod]
public void Check_ProcessDormantApplications()
{
////arrange
var applicationId = new List<long>()
{
//put here some ids
};
DormantServiceAdapter.Stub(x => x.GetDormantApplications()).Return(applicationId);
var target = new DormantApplicationsBusinessLogic(DormantServiceAdapter, logger);
////act
target.ProcessDormantApplications();
////assert
foreach (var id in applicationId)
{
DormantServiceAdapter.AssertWasCalled(x => x.UpdateDormantApplications(id));
}
}
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;
}