I would agree that as presented the test does not test the void method. It does not even verify that an expected exception is thrown when a certain condition arises. All it does it verify that something runs and does not throw an exception. Void method can be tested but you will need to look at the use of a mocking framework and some form of dependency injection. In TDD you should be developing the test before producing the code and therefore the test is defining what the code should do.
Here is sample of void method being tested:
public void CreateModel(string activityId, string documentModel)
{
this.UpdateModel(activityId, documentModel);
}
it uses the following private method:
public void UpdateModel(string activityId, string documentModel)
{
FlattenedActivityModel activityModel = null;
IAzureContainer azureContainer = ClassContainer.Resolve<IAzureContainer>();
IPublishActivityEvents publisher = ClassContainer.Resolve<IPublishActivityEvents>();
var searchQuery = string.Format(CultureInfo.CurrentCulture, "activityId:{0}", activityId);
var activityModels = azureContainer.ActivitySearch(string.Empty, searchQuery);
if (activityModels != null)
{
if (activityModels.Count > 0)
{
activityModel = activityModels[0];
}
}
FlattenedDocumentModel model = new FlattenedDocumentModel(activityModel, documentModel);
var metadata = JsonConvert.SerializeObject(model);
publisher.PublishDocumentMetadata(metadata, activityModel.RootName, model.MetadataFileName);
}
One of the tests to validate the code would look like:
[TestMethod]
public void When_CreateModel_Is_Called_Then_Model_Is_Created_As_Expected()
{
var activityContent = File.ReadAllText(@"TestData\FlattenedActivity.json");
var activity = JsonConvert.DeserializeObject<FlattenedActivityModel>(activityContent);
var documentRequest = File.ReadAllText(@"TestData\DocumentRequest.json");
var activityId = Guid.NewGuid().ToString();
var document1 = new FlattenedDocumentModel
{
DocumentId = Guid.NewGuid().ToString(),
ActivityId = activityId
};
var documents = new Collection<FlattenedDocumentModel>
{
document1
};
var azureConatiner = new Mock<IAzureContainer>();
var activities = new Collection<FlattenedActivityModel>();
activity.ActivityId = activityId;
activities.Add(activity);
var queryString = string.Format("activityId:{0}", activityId);
azureConatiner.Setup(a => a.ActivitySearch(string.Empty, queryString)).Returns(activities);
var publishActivityEvents = new Mock<IPublishActivityEvents>();
ClassContainer.InitialiseRegistrations();
ClassContainer.RegisterInstance(azureConatiner.Object);
ClassContainer.RegisterInstance(publishActivityEvents.Object);
var target = new DocumentApi();
target.UpdateModel(activityId, documentRequest);
FlattenedDocumentModel expectedModel = new FlattenedDocumentModel(activity, documentRequest);
var expectedMetadata = JsonConvert.SerializeObject(expectedModel);
azureConatiner.Verify(a => a.ActivitySearch(string.Empty, queryString), Times.Once());
publishActivityEvents.Verify(p => p.PublishDocumentMetadata(expectedMetadata, activity.RootName, expectedModel.MetadataFileName));
}
This test verifies that the internals of the void method is making the expected calls, with the expected values and the expected number of times.(I would point out that this sample is WIP and has some issues that need further tests e.g. activityModel being null).