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));
}
}
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'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
I have a class as below :
public class CosmosRepository: ICosmosRepository
{
private ICosmoDBSettings cosmoDbSettings;
private CosmosClient cosmosClient;
private static readonly object syncLock = new object();
// The database we will create
private Database database;
public CosmosRepository(ICosmoDBSettings cosmoDBSettings)
{
this.cosmoDbSettings = cosmoDBSettings;
this.InitializeComponents();
}
private void InitializeComponents()
{
try
{
if (cosmosClient != null)
{
return;
}
lock (syncLock)
{
if (cosmosClient != null)
{
return;
}
this.cosmosClient = new CosmosClient(
cosmoDbSettings.CosmosDbUri
, cosmoDbSettings.CosmosDbAuthKey
, new CosmosClientOptions
{
ConnectionMode = ConnectionMode.Direct
}
);
this.database = this.cosmosClient.CreateDatabaseIfNotExistsAsync(cosmoDbSettings.DocumentDbDataBaseName).Result;
}
}
catch (Exception ex)
{
throw ex;
}
}
}
I have my repository method as:
Don't bother about hardcoded values.
public async Task<Employee> GetById()
{
var container = this.database.GetContainer("Employees");
var document = await container.ReadItemAsync<Employee>("44A85B9E-2522-4BDB-891A-
9EA91F6D4CBF", new PartitionKey("PartitionKeyValue"));
return document.Response;
}
Note
How to write Unit Test(MS Unit tests) in .NET Core with respect to Cosmos Database?
How to mock CosmosClient and all its methods.
Could someone help me with this issue?
My UnitTests looks like:
public class UnitTest1
{
private Mock<ICosmoDBSettings> cosmoDbSettings;
private Mock<CosmosClient> cosmosClient;
private Mock<Database> database;
[TestMethod]
public async Task TestMethod()
{
this.CreateSubject();
var databaseResponse = new Mock<DatabaseResponse>();
var helper = new CosmosDBHelper(this.cosmoDbSettings.Object);
this.cosmosClient.Setup(d => d.CreateDatabaseIfNotExistsAsync("TestDatabase", It.IsAny<int>(), It.IsAny<RequestOptions>(), It.IsAny<CancellationToken>())).ReturnsAsync(databaseResponse.Object);
var mockContainer = new Mock<Container>();
this.database.Setup(x => x.GetContainer(It.IsAny<string>())).Returns(mockContainer.Object);
var mockItemResponse = new Mock<ItemResponse<PortalAccount>>();
mockItemResponse.Setup(x => x.StatusCode).Returns(It.IsAny<HttpStatusCode>);
var mockPortalAccount = new PortalAccount { PortalAccountGuid = Guid.NewGuid() };
mockItemResponse.Setup(x => x.Resource).Returns(mockPortalAccount);
mockContainer.Setup(c => c.ReadItemAsync<PortalAccount>(It.IsAny<string>(),It.IsAny<PartitionKey>(), It.IsAny<ItemRequestOptions>(), It.IsAny<CancellationToken>())).ReturnsAsync(mockItemResponse.Object);
var pas = helper.GetById().Result;
Assert.AreEqual(pas.PortalAccountGuid, mockPortalAccount.PortalAccountGuid);
}
public void CreateSubject(ICosmoDBSettings cosmoDBSettings = null)
{
this.cosmoDbSettings = cosmoDbSettings ?? new Mock<ICosmoDBSettings>();
this.cosmoDbSettings.Setup(x => x.CosmosDbUri).Returns("https://localhost:8085/");
this.cosmoDbSettings.Setup(x => x.CosmosDbAuthKey).Returns("C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==");
this.cosmoDbSettings.Setup(x => x.DocumentDbDataBaseName).Returns("TestDatabase");
this.database = new Mock<Database>();
this.cosmosClient = new Mock<CosmosClient>();
}
}
Note:
Exception:
Response status code does not indicate success: 404 Substatus: 0 Reason: (Microsoft.Azure.Documents.DocumentClientException: Message: {"Errors":["Resource Not Found"]}
I'm not creating a document. directly I'm fetching the document because I'm returning the mock response only. Is it correct??
Someone shoot me as I can't see what I'm missing but the inner property of my stubbed object is null which is breaking my tests.
Many Thanks,
James
CommandService
public void Create()
{
var risk = _queryService.GetRisk(creatable.HeaderId);
if(risk.HeaderId != null) // HeaderId IS NULL??
{
...
}
}
QueryService
public Risk GetRisk(int headerId)
{
return _repository.GetRisk(headerId);
}
Unit test
[TestInitialize]
public void SetUp()
{
_mockRepository = new MockRepository();
_queryService = _mockRepository.Stub<IQueryService>();
_commandService = new CoreCommandService(_queryService);
}
public void MyTest()
{
var runRisk = new RunRisk { HeaderId = 10 };
_queryService.Stub(x => x.GetRisk(199)).Repeat.Any().Return(runRisk);
var result = _commandService.Create();
}
need to use the following to fix it.
MockRepository.GenerateMock<IQueryService>();
I have a problem with an integration test I am writing. I need to perform cleanup at the end of the test by removing the categories (from the list of available categories) in Outlook that I have added during the test. I do this as follows for the 'Filed' category:
using Microsoft.Office.Interop.Outlook;
var outlookApplication = new Application();
outlookApplication.Session.Categories.Remove("Filed");
This fails to remove the category, but not consistently. When I debug the code it works but not when I run the tests.
UPDATE:
Here's all the test code:
[TestFixture]
public class BootstrapperTest
{
private bool containsFiled;
private bool containsPending;
private Application outlookApplication = new Application();
[Test]
public void CanCreateFiledCategory()
{
var bootstrapper = new Bootstrapper();
bootstrapper.LoadCategoriesIntoOutlook(outlookApplication);
var filedCategoryFound = outlookApplication.Session.Categories.Cast<Category>().Any(category => category.Name == "Filed");
Assert.That(filedCategoryFound, Is.EqualTo(true));
}
[Test]
public void CanCreatePendingCategory()
{
var bootstrapper = new Bootstrapper();
bootstrapper.LoadCategoriesIntoOutlook(outlookApplication);
var pendingCategoryFound = outlookApplication.Session.Categories.Cast<Category>().Any(category => category.Name == "Pending");
Assert.That(pendingCategoryFound, Is.EqualTo(true));
}
[SetUp]
public void Setup()
{
containsFiled = DoesCategoryNameExist(outlookApplication.Session.Categories, "Filed");
containsPending = DoesCategoryNameExist(outlookApplication.Session.Categories, "Pending");
}
[TearDown]
public void TearDown()
{
RemoveAllCategoriesFromOutlook();
}
private bool DoesCategoryNameExist(Categories categoryList, string categoryName)
{
return categoryList.Cast<Category>().Any(category => category.Name == categoryName);
}
private void RemoveAllCategoriesFromOutlook()
{
var containsFiledNow = DoesCategoryNameExist(outlookApplication.Session.Categories, "Filed");
var containsPendingNow = DoesCategoryNameExist(outlookApplication.Session.Categories, "Pending");
if (!containsFiled && containsFiledNow) outlookApplication.Session.Categories.Remove("Filed");
if (!containsPending && containsPendingNow) outlookApplication.Session.Categories.Remove("Pending");
}
}
And the method it is testing:
public void LoadCategoriesIntoOutlook(Application outlookApplication)
{
var categories = outlookApplication.Session.Categories;
var filedCategoryNameExists = DoesCategoryNameAlreadyExist(categories, FiledCategoryName);
var pendingCategoryNameExists = DoesCategoryNameAlreadyExist(categories, PendingCategoryName);
var filedCategoryColourIsUsed = IsCategoryColorAlreadyUsed(categories, FiledCategoryColor);
var pendingCategoryColourIsUsed = IsCategoryColorAlreadyUsed(categories, PendingCategoryColor);
if (!filedCategoryNameExists)
{
if (filedCategoryColourIsUsed)
{
var categoryToBeChangedToFiled =
categories.Cast<Category>()
.Where(category => category.Color == FiledCategoryColor)
.FirstOrDefault();
categoryToBeChangedToFiled.Name = FiledCategoryName;
}
else
{
categories.Add(FiledCategoryName, FiledCategoryColor);
}
}
if (!pendingCategoryNameExists)
{
if (pendingCategoryColourIsUsed)
{
var categoryToBeChangedToPending =
categories.Cast<Category>()
.Where(category => category.Color == PendingCategoryColor)
.FirstOrDefault();
categoryToBeChangedToPending.Name = PendingCategoryName;
}
else
{
categories.Add(PendingCategoryName, PendingCategoryColor);
}
}
}
You should log whether Categories.Remove is even called (via Trace.TraceInformation()) to see if there is an error in your branch condition when run in non-DEBUG mode. Categories.Remove does work reliably, it must be an error in your condition. If so, you won't see the logging statements.
private void RemoveAllCategoriesFromOutlook()
{
var containsFiledNow = DoesCategoryNameExist(outlookApplication.Session.Categories, "Filed");
var containsPendingNow = DoesCategoryNameExist(outlookApplication.Session.Categories, "Pending");
if (!containsFiled && containsFiledNow)
{
outlookApplication.Session.Categories.Remove("Filed");
Trace.TraceInformation("Deleted Filed Category!")
}
if (!containsPending && containsPendingNow)
{
outlookApplication.Session.Categories.Remove("Pending");
Trace.TraceInformation("Deleted Pending Category!")
}
}
Also, since you create Categories based off of color (see filedCategoryColourIsUsed), containsFiled may return FALSE, even though you created it via rename (Category.Name = "Filed"), not via Categories.Add(). Your issue is that DoesCategoryNameExist does not consider category color during your Setup test fixture. The following Setup() code should correct this problem...
[SetUp]
public void Setup()
{
containsFiled = DoesCategoryNameExist(outlookApplication.Session.Categories, "Filed") || IsCategoryColorAlreadyUsed(categories, FiledCategoryColor);
containsPending = DoesCategoryNameExist(outlookApplication.Session.Categories, "Pending") || IsCategoryColorAlreadyUsed(categories, PendingCategoryColor);
}