Reputation: 2633
When I run my test code normally, NUnit informs me that the test has failed. The value of result.Contacts
is 3 instead of the expected 1. When the testcode is run with a breakpoint on the assert statement in the test code, the test does not fail. I suspect this is a problem related to multithreading.
This is my test code
[Test]
public async Task Method_Scenario_IncreasesCount()
{
// Arrange
const int employeeId = 1;
const string managerId = "asdf";
// Act
var result = await _uut.Contact(managerId , employeeId);
// Assert
Assert.That(result.Contacts, Is.EqualTo(1));
}
This is the code under test
public async Task<MyObject> Contact(string managerId, int employeeId)
{
var today = DateTime.UtcNow.Date;
var myStoredObject = _myObjectRepository.GetAll().Include(p => p.Employee).First(x => x.Employee.Id == employeeId);
myStoredObject.Contacts += 1;
myStoredObject.LastContact = today;
var dates = new List<DateTime>
{
myStoredObject.FirstDate,
myStoredObject.SecondDate,
myStoredObject.ThirdDate
};
if (!dates.Contains(today))
{
await _logging.Log(myStoredObject, Log.Extra);
await _myObjectRepository.UpdateAsync(myStoredObject);
}
return myStoredObject;
}
The _myObjectRepository
and _logging
objects are mocked using Moq
; and the myStoredObject
is predefined by me, so I know the value of Contacts is 0 to begin with.
Why does the test only pass when I use a breakpoint on the assert statement? And how do I resolve this issue?
Edit
I've also tried using Moq
to do this:
_mock.Verify(r => r.UpdateAsync(It.Is<MyObject>(m => m.Contacts == 1)));
But this fails as well, with a MockException saying:
Expected invocation on the mock at least once, but was never performed.
However, if I step through the program, I can see that this method is called with a MyObject
that has Contacts = 1
.
Upvotes: 2
Views: 86
Reputation: 2601
It's hard to say what might be causing your problem without seeing your [SetUp]
code. I notice that your mocks and unit under test are member variables - maybe there is a problem with shared state with another test. I was able to write the same test, and have it pass consistently
[Test]
public async Task Method_Scenario_IncreasesCount()
{
// Arrange
const int employeeId = 55378008;
var existingEntity = new MyObject {Employee = new Employee {Id = employeeId}};
var repo = Mock.Of<IMyObjectRepo>(r => r.GetAll() == new[] {existingEntity}.AsQueryable());
var uut = new MyUut(repo, Mock.Of<ILog>());
// Act
var entity = await uut.Contact(string.Empty, employeeId);
// Assert
Assert.That(entity.Contacts, Is.EqualTo(1));
Mock.Get(repo).Verify(r => r.UpdateAsync(entity));
}
Upvotes: 2