1
\$\begingroup\$

Im working on a small desktop app which controls services on a server. For controlling services i am using ServiceController class. What i want to do is; testing my code and abstract the ServiceController class from my code. So i did something like below.

  public interface IServiceControllerWrapper
{          
    string ServerNameOrIP { get; }    
    int Status { get; }
    bool CanStop { get;  }       
    void StartService();

}

 public class ServiceControllerWrapper : IServiceControllerWrapper
{
    ServiceController _controller;
    const string ServiceName = "W3SVC";


    public ServiceControllerWrapper(string serverNameOrIP)
    {
        _controller = new ServiceController(ServiceName, serverNameOrIP);
    }     


    public string ServerNameOrIP { get { return _controller.MachineName; } }

    public int Status
    {
        get
        {
            switch (_controller.Status)
            {
                case ServiceControllerStatus.ContinuePending:
                case ServiceControllerStatus.PausePending:
                case ServiceControllerStatus.Paused:
                    return 4;
                case ServiceControllerStatus.StopPending:
                case ServiceControllerStatus.Stopped:
                    return 0;
                case ServiceControllerStatus.StartPending:
                case ServiceControllerStatus.Running:
                    return 1;
                default:
                    return -1;
            }
        }
    }


    public bool CanStop
    {
        get
        {
            return _controller.CanStop;
        }
    }

    public void StartService()
    {
        _controller.Start();
    }

   //shortened

}

and i am using this class within another named ServerContext. Implementation is;

   public interface IServerContext
{
    string ServerName { get; }
    IServerContext Parent { get; }       
    IServiceControllerWrapper Controller { get; }
    bool HasError { get; set; }
    int GetServiceStatus();       
}

  public class ServerContext : IServerContext
{
    IServerContext _parent;
    IServiceControllerWrapper _controller;     


    public ServerContext(IServerContext parent, IServiceControllerWrapper wrapper)
    {
        _parent = parent;
        _controller = wrapper;
    } 


    public string ServerName { get { return _controller.ServerNameOrIP; }}

    public IServerContext Parent
    {
        get
        {
            return _parent;
        }          
    }

    public IServiceControllerWrapper Controller
    {
        get
        {
            return _controller;
        }
    }

    public bool HasError { get; set; }


    public int GetServiceStatus()
    {
       return _controller.Status;
    }        

 }

My question here is, i am tryint to test ServerContext and ServiceControllerWrapper but i cant manage to create fake objects. this test method always throws exception because ServerName is null.How can i arrange this code to pass test and or how can i test those classes?

      [Fact]
    public void ServerName_CannotBeEmpty()
    {
        Mock<IServiceControllerWrapper> _controller = new Mock<IServiceControllerWrapper>();
        ServerContext serverContext = new ServerContext(null, _controller.Object);
        //this code fails. 
        serverContext.ServerName.Should().Not.Be.NullOrEmpty();
    }

Any suggestions are welcome. Note: i am using moq,xunit and SharpTestsEx libraries for testing.

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

You'll have to do something like (this will work for Moq, change the api usage to match your Mocking framework).

_controller.Setup(p=>p.ServerNameOrIP).Returns("testServerName");

before you call your assert statement.

\$\endgroup\$
1
  • \$\begingroup\$ oppps you are right.It seems that i need to learn mocking framework first and than testing. \$\endgroup\$ Commented May 30, 2012 at 12:40
0
\$\begingroup\$

If your mocking framework is similar to the one I use, you probably need to stub ServerNameOrIP on your injected IServiceControllerWrapper mock. It is not uncommon for mocked objects to return default(T) for anything not yet stubbed.

As an aside, I would suggest modifying your IServiceControllerWrapper to eliminate your Controller property. The purpose of the wrapper is only to expose those methods/properties that your code requires from ServiceController while hiding the fact that you are using a ServiceController object to execute them. If someone else were to code against your wrapper and use this property, they have effectively re-coupled the code to ServiceController.

\$\endgroup\$
1
  • \$\begingroup\$ thanks for your suggestions. I edited the code and the test methos to reflect my question clearly. I think i dont know how to stub ServerNameOrIP. Maybe i didnt understand testing frameworks clearly. \$\endgroup\$ Commented May 30, 2012 at 8:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.