Hi,
Of course no developer wants to write software that is not Unit Testable, else you going to spend 1 months building a project and 2 month debugging it! Why not get your Unit Tests started up front, then write all your use cases as unit tests and bang them one by one.
PowerScribe360 has allot of new features for Radiologists and we want to test when events get published or received, as well as fake all the internal dependencies of the COM e.g. Terminate require PowerScribe to be open, and of course when unit testing, this is a no no, as we want NO external dependencies.
So we will create a wrapper, here is the code, and you can get it from here as well:
Source Code
Note that PowerScribe360 is a class I created to wrap up the RadWhereCom into a public property e.g.
public partial class Powerscribe360 { public IMyRadWhereCom radWhereCom; public Powerscribe360(IMyRadWhereCom myRadWhereCom) { radWhereCom = myRadWhereCom; WireUpEvents(); } private void WireUpEvents() { radWhereCom.UserLoggedIn += UserLoggedIn; radWhereCom.UserLoggedOut += UserLoggedOut; radWhereCom.AudioTranscribed += AudioTranscribed; radWhereCom.AccessionNumbersChanged += AccessionNumbersChanged; radWhereCom.ReportFinished += ReportFinished; radWhereCom.ReportClosed += ReportClosed; radWhereCom.ReportOpened += ReportOpened; radWhereCom.ReportChanged += ReportChanged; radWhereCom.DictationStarted += DictationStarted; radWhereCom.DictationStopped += DictationStopped; radWhereCom.Terminated += Terminated; } public void UserLoggedIn(string userName) { Hub.Publish(HubEvents.DictationSystem.LoginCompleted); } public void UserLoggedOut(string userName) { radWhereCom.Terminate(); Hub.Publish(HubEvents.DictationSystem.PSInterop.LoggedOff); } }
e.g.
var ps = new Powerscribe360(radWhereCom);
ps.radWhereCom.UserLoggedOut += Raise.Event(“Foo”);
Notice below, that if we did not MOCK RadWhereCOM, the call to radWhereCom.Terminate() in our event subscribe would fail.
The benefit is now that any “Cause” happening in PS360, we can fake the “effect” e.g.
radWhereCom.Terminate().ReturnsForAnyArgs(true);
[Test] public void ShouldRaiseUserLoggedInEvent() { // arrange var wasCalled = false; Hub.Subscribe(HubEvents.DictationSystem.LoginCompleted, () => { wasCalled = true; }, "Foo"); var radWhereCom = Substitute.For<IMyRadWhereCom>(); var ps = new Powerscribe360(radWhereCom); // act ps.radWhereCom.UserLoggedIn += Raise.Event<RWC_UserLoggedInHandler>("Foo"); // Assert Assert.IsTrue(wasCalled); } [Test] public void ShouldRaiseUserLoggedOffEvent() { // arrange var wasCalled = false; Hub.Subscribe(HubEvents.DictationSystem.PSInterop.LoggedOff, () => { wasCalled = true; }, "Foo"); var radWhereCom = Substitute.For<IMyRadWhereCom>(); radWhereCom.Terminate().ReturnsForAnyArgs(true); var ps = new Powerscribe360(radWhereCom); // act ps.radWhereCom.UserLoggedOut += Raise.Event<RWC_UserLoggedOutHandler>("Foo"); // assert Assert.IsTrue(wasCalled); }
Suppose this is in the constructor for our Powerscribe360 class:
radWhereCom.UserLoggedIn += UserLoggedIn;
Then the test above will fail if the line below is removed.
Now the code will never throw an exception when Terminate or any other PowerScribe 360 dependency is called:
Happy Coding!