Let's consider the below example:
internal class Meeting
{
public int Id { get; set; }
}
internal class DailyRoomReservation
{
private ISet<Meeting> _meetings { get; set; } = new HashSet<Meeting>();
internal void ScheduleMeeting(Meeting meeting)
{
if (_meetings.Contains(meeting)) throw new InvalidOperationException();
_meetings.Add(meeting);
}
}
Assuming that DailyRoomReservation
is my aggregate root (I intentionally ommited most of business logic for simplicity's sake), how should I test this? It is known good practise to expose only command methods for aggregates (CQS terminology), especially when using CQRS in big picture. Furthermore I have no business need for exposing the _meetings
property (testing purpose of course is not a good reason to do this). I wrote following tests:
[Test]
internal void ScheduleNewMeeting_ShouldSucceed()
{
var uniqueMeeting = new Meeting() { Id = 1};
var dailyRoomReservation = new DailyRoomReservation();
dailyRoomReservation.ScheduleMeeting(uniqueMeeting);
}
[Test]
internal void ScheduleSameMeetingTwice_ShouldFail()
{
var meeting = new Meeting() { Id = 1};
var dailyRoomReservation = new DailyRoomReservation();
dailyRoomReservation.ScheduleMeeting(meeting);
Action scheduleMeeting = () => dailyRoomReservation.ScheduleMeeting(meeting);
scheduleMeeting.Should().ThrowExactly<InvalidOperationException>();
}
And they work pretty well, however I still cannot validate at that point whether the meeting has been really added. How can I refine my approach?