Consider the following method that stops a service:
Public Function StopService(ByVal serviceName As String, ByVal timeoutMilliseconds As Double) As Boolean
Try
Dim service As New ServiceController(serviceName)
Dim timeout As TimeSpan = TimeSpan.FromMilliseconds(timeoutMilliseconds)
service.[Stop]()
If timeoutMilliseconds <= 0 Then
service.WaitForStatus(ServiceControllerStatus.Stopped)
Else
service.WaitForStatus(ServiceControllerStatus.Stopped, timeout)
End If
Return service.Status = ServiceControllerStatus.Stopped
Catch ex As Win32Exception
'error occured when accessing a system API'
Return False
Catch ex As TimeoutException
Return False
End Try
End Function
In order to unit test the the method I basically have two options:
ServiceController
class's methods I need into an interface I can control. This interface can then be injected into the service class (a.k.a Inversion of Control). This way I have a loosely coupled code and can use the traditional mocking frameworks to test.ServiceController
to
return canned results for testing
purposes. I agree that for domain model code that using the "traditional" unit testing approach makes the most sense as this would lead to a design that is easiest to maintain. However, for code that deals with the .net implementation of Windows API related stuff (file system, services, etc), is there really an advantage to going thru the extra work to get "traditionally" testable code?
It's hard for me to see the disadvantages of using Microsoft Moles for things such as ServiceController
(or the File
object). I really don't see any advantage of doing the traditional approach in this case. Am I missing anything?
Unit testing ensures that all code meets quality standards before it's deployed. This ensures a reliable engineering environment where quality is paramount. Over the course of the product development life cycle, unit testing saves time and money, and helps developers write better code, more efficiently.
Unit tests are a way to ensure your code still works after you make changes. They can be a challenge to get right, but they're worth the effort. By writing unit tests, you can ensure your code still works as expected and prevent regressions. Most developers agree that unit testing is a good practice, but few do it.
A typical unit test contains 3 phases: First, it initializes a small piece of an application it wants to test (also known as the system under test, or SUT), then it applies some stimulus to the system under test (usually by calling a method on it), and finally, it observes the resulting behavior.
Great question btw.. Just had a look at MS Moles video right now. Although I'm skeptical of MS Unit-testing tools, I must say this one looks interesting. My comparison stands at:
ServiceManager.StartService(name)
could abstract the details {1. ServiceController.GetServices(), 2. handle case where ServiceController.Status != Stopped, 3. ServiceController.Start()}. The mock/fake approach here would involve less work than setting up 3 delegates. Here this approach is an opportunity to improve your design by coming up with meaningful contracts/interfaces (also allows you to hide stuff that you don't care about -- e.g. Winapi semantics, constants, etc)I believe that this is a good case for mocking and there're some advantages of doing it with IoC:
You do actual unit-testing, as your tests aren't testing underlying layers - this would be an integration test -.
Easy to plug and unplug a mock object.
You don't need to define a "fake" implementation on each stub. You've a "fake", mocked implementation by configuration.
For me, the first reason is the most important.
Why don't to use Moles? Because I believe it's not the right tool for something like this. Moles is more for things like I want a fixed value of DateTime.Now to an specific time, so you can test some code in some situation whenever you want with no troubles.
Moles is an easy way to auto-mock certain methods, properties in specific tests, while IoC+fake, it's to isolate your test.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With