Unit testing a method whose statements run on different task - c#

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

Related

Mock test returning null in NUnit .Net 5.0

I'm trying to make a simple mock tests in .Net 5.0 and NUnit. It's working for everything, but not for an specific method... and I can't find the solution.
First I have a logic class:
public class GameBusiness : IGameBusiness
{
private readonly IGameRepository _gameRepository;
public GameBusiness(IGameRepository gameRepository)
{
_gameRepository = gameRepository;
}
public async Task<Game> CreateGame()
{
var drawCard = GenerateRandomCardValue();
var newGame = new Game() { LastDrawedCard = drawCard };
return await _gameRepository.Insert(newGame);
}
public async Task<Game> GetGame(int gameId)
{
return await _gameRepository.GetById(gameId);
}
private int GenerateRandomCardValue()
{
var random = new Random();
return random.Next(1, 13);
}
}
And in My Test Class, I Have
private readonly Mock<IGameRepository> _gameRepository = new Mock<IGameRepository>();
private readonly GameBusiness _gameBusiness;
public GameRepositoryTest()
{
_gameBusiness = new GameBusiness(_gameRepository.Object);
}
[SetUp]
public void Setup()
{
}
[Test]
public async Task GetGame_ShouldReturnGame_WhenGameExists()
{
var gameId = 5;
var game = new Game()
{
Id = 5,
LastDrawedCard = 3
};
_gameRepository.Setup(x => x.GetById(gameId)).ReturnsAsync(game);
var gameResult = await _gameBusiness.GetGame(5);
Assert.AreEqual(gameId, gameResult.Id);
}
[Test]
public async Task CreateGame_ShouldReturnNewGameWithLastDrawedCard()
{
var newGame = new Game()
{
Id = 5,
LastDrawedCard = 3
};
_gameRepository.Setup(x => x.Insert(new Game())).ReturnsAsync(newGame);
var newGameResult = await _gameBusiness.CreateGame();
Assert.IsTrue(newGame.LastDrawedCard > 0);
}
}
So my problem is that inside CreateGame_ShouldReturnNewGameWithLastDrawedCard() I create a mock that should return to me a Game object assing to newGame. But it ALWAYS return null.
When debuggin, the line in CreateGame() is returning null
return await _gameRepository.Insert(newGame);
For others methods, like
_gameRepository.Setup(x => x.GetById(gameId)).ReturnsAsync(game);
var gameResult = await _gameBusiness.GetGame(5);
It works perfect. What I'm missing here?
The issue is that the arguments do not match what was set up so it will return null by default.
Refactor to use an argument matcher and also to capture the model that was created within the member under test
[Test]
public async Task CreateGame_ShouldReturnNewGameWithLastDrawedCard() {
//Arrange
_gameRepository
.Setup(x => x.Insert(It.IsAny<Game>())) //<-- uses a catch-all matcher
.ReturnsAsync((Game arg) => arg); //<-- captures passed argument and returns it
//Act
var actual = await _gameBusiness.CreateGame();
//Assert
Assert.IsTrue(actual != null);
Assert.IsTrue(actual.LastDrawedCard > 0);
}
Reference Moq Quickstart

How to verify that a method was called with Moq?

I'm trying to validate that SetFirefoxOptions() is called when I call GetFirefoxDriver(). But for whatever reason, Moq keeps telling me that it wasn't called. What am I doing wrong?
Here's my test:
[TestMethod]
public void ShouldSetFirefoxOptions()
{
var stubCapabilities = new Mock<SauceCaps>().Object;
var mockManager = new Mock<DriverManager>();
mockManager.Setup(
m => m.GetFirefoxDriver(stubCapabilities)).
Returns(It.IsAny<IWebDriver>());
mockManager.Verify(
m => m.SetFirefoxOptions(stubCapabilities));
}
DriverManager.cs:
public class DriverManager : IDriverManager
{
public virtual Dictionary<string, object> SauceOptions { get; private set; }
public DriverManager()
{
}
public virtual IWebDriver GetFirefoxDriver(SauceCaps sauceCaps)
{
var browserOptions = SetFirefoxOptions(sauceCaps);
return new RemoteWebDriver(new Uri("https://ondemand.saucelabs.com/wd/hub"),
browserOptions.ToCapabilities(), TimeSpan.FromSeconds(600));
}
public virtual FirefoxOptions SetFirefoxOptions(SauceCaps sauceCaps)
{
return new FirefoxOptions
{
BrowserVersion = sauceCaps.BrowserVersion,
PlatformName = sauceCaps.Os
};
}
}
The problem with your code is that it is unclear what is your System Under Test. You are mocking and testing the same class at the same time. Although it is technicaly possible using moq (using CallBase) it is in principle wrong approach.
The one possibility is to extract SetFirefoxOptions into separate interface and inject it into the DriverManager, e.g.
public interface IFirefoxOptionCreator
{
FirefoxOptions SetFirefoxOptions(SauceCaps sauceCaps);
}
public DeviceManager(IFirefoxOptionCreator optionCreator)
{
_optionCreator = optionCreator;
}
public virtual IWebDriver GetFirefoxDriver(SauceCaps sauceCaps)
{
var browserOptions = _optionCreator.SetFirefoxOptions(sauceCaps);
return new RemoteWebDriver(new Uri("https://ondemand.saucelabs.com/wd/hub"),
browserOptions.ToCapabilities(), TimeSpan.FromSeconds(600));
}
then you could easily verify is interface method was called within your unit tests:
[TestMethod]
public void ShouldSetFirefoxOptions()
{
// Arrange
var stubCapabilities = new Mock<SauceCaps>().Object;
var optionCreatorMock = new Mock<IFirefoxOptionCreator>();
optionCreatorMock.Setup(m => m.SetFirefoxOptions(It.IsAny<SauceCaps>()))
.Returns(new FirefoxOptions());
var sut = new DriverManager();
// Act
_ = sut.GetFirefoxDriver(stubCapabilities);
// Assert
optionCreatorMock.Verify(m => m.SetFirefoxOptions(stubCapabilities));
}

How to moq setup IRepository<T>

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);

Rhino Mocks help needed

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));
}
}

How do i assert that a unit tested method return True?

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;
}

Categories

Resources