patterncsharpMinor
UnitTesting with Mocking and Dependency Injection using Ninject
Viewed 0 times
mockingunittestingwithninjectdependencyinjectionusingand
Problem
I have the following scenario that I have not come across so far using Ninject. I have the following class structure (simplified for easy of reading :]). First the abstract base class for all
```
public abstract class DocumentController : IDocumentController, IDisposable
{
...
private IMessageBoxService messageBoxService;
private IUndoRedoManager undoRedoManager;
private FileSystemObserver observer;
private bool fileChanging;
public DocumentController(IMessageBoxService messageBoxService)
{
if (messageBoxService == null)
throw new ArgumentNullException("messageBoxService");
this.messageBoxService = messageBoxService;
}
...
private void FileChangedHandler(string p)
{
if (!fileChanging && p.CompareNoCase(FilePath))
{
fileChanging = true;
try
{
(View as Form).UIThread(() =>
{
DialogResult result = messageBoxService.DisplayMessage(
(Form)View,
String.Format(
MessageStrings.DocumentController_DocumentChanged,
FilePath,
Constants.Trademark),
CaptionStrings.ChangeNotification,
MessageBoxButtons.YesNo, MessageBoxIcon.Information);
if (result == DialogResult.Yes)
{
if (TryClose(new FormClosingEventArgs(CloseReason.None, false)))
{
MediatorService.Instance.NotifyColleagues(
MediatorService.Messages.OpenDocuments,
new List() { FilePath });
Dispose();
}
}
});
}
finally
{
fileChanging = false;
IDocuments```
public abstract class DocumentController : IDocumentController, IDisposable
{
...
private IMessageBoxService messageBoxService;
private IUndoRedoManager undoRedoManager;
private FileSystemObserver observer;
private bool fileChanging;
public DocumentController(IMessageBoxService messageBoxService)
{
if (messageBoxService == null)
throw new ArgumentNullException("messageBoxService");
this.messageBoxService = messageBoxService;
}
...
private void FileChangedHandler(string p)
{
if (!fileChanging && p.CompareNoCase(FilePath))
{
fileChanging = true;
try
{
(View as Form).UIThread(() =>
{
DialogResult result = messageBoxService.DisplayMessage(
(Form)View,
String.Format(
MessageStrings.DocumentController_DocumentChanged,
FilePath,
Constants.Trademark),
CaptionStrings.ChangeNotification,
MessageBoxButtons.YesNo, MessageBoxIcon.Information);
if (result == DialogResult.Yes)
{
if (TryClose(new FormClosingEventArgs(CloseReason.None, false)))
{
MediatorService.Instance.NotifyColleagues(
MediatorService.Messages.OpenDocuments,
new List() { FilePath });
Dispose();
}
}
});
}
finally
{
fileChanging = false;
Solution
Here be dragons :P
This is a conceptual minefield.
I have done this exact thing and can relate, you instinctively want to test a lifecycle.
a start-to-finish stub implementation.....
but don't.
the golden rule of unit testing is never test an interface. test an implementation.
I'd add a second rule personally, don't test module interaction.
If you have
if A fires when called correctly ...good.
if B activates (regardless of who called it) ... good;
if B returns an expected IC ...good.
does it MATTER if A->b->c evaluates properly?
infact i would suggest not only does it not. but if you require it does, your individual components are designed wrong.
you have no reason to test Ninject.
that is like sending yourself a letter to check the formatting and quizzing the postman.
if you want to test an abstract class, try not to. why did you MAKE the abstract class? to be used in an implementation.
test the implementation
This is a conceptual minefield.
I have done this exact thing and can relate, you instinctively want to test a lifecycle.
a start-to-finish stub implementation.....
but don't.
the golden rule of unit testing is never test an interface. test an implementation.
I'd add a second rule personally, don't test module interaction.
If you have
A->activates->B-> returns a Cif A fires when called correctly ...good.
if B activates (regardless of who called it) ... good;
if B returns an expected IC ...good.
does it MATTER if A->b->c evaluates properly?
infact i would suggest not only does it not. but if you require it does, your individual components are designed wrong.
you have no reason to test Ninject.
that is like sending yourself a letter to check the formatting and quizzing the postman.
if you want to test an abstract class, try not to. why did you MAKE the abstract class? to be used in an implementation.
test the implementation
Code Snippets
A->activates->B-> returns a CContext
StackExchange Code Review Q#131456, answer score: 7
Revisions (0)
No revisions yet.