测试使用模拟的WCF服务

时间:2014-09-26 13:14:39

标签: c# wcf unit-testing nunit impersonation

我正在通过NUnit自动转换传统WCF服务的一些现有集成测试。当前测试调用WCF服务的部署版本;我想要做的是让测试直接/内部地到达服务类(MyService.svc.cs)。

我遇到的问题是该服务使用模拟:

    //this is a method in MyService.svc.cs
    public SomeObject GetSomeObject()
    {
      using (GetWindowsIdentity().Impersonate())
      {
        //do some stuff
      }

      return null;
    }

    private WindowsIdentity GetWindowsIdentity()
      {
        var callerWinIdentity = ServiceSecurityContext.Current.WindowsIdentity;

        var cf = new ChannelFactory<IMyService>();
        cf.Credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;

        return callerWinIdentity;
    }

问题是,当我从单元测试中调用ServiceSecurityContext.Current时,它始终为null。

模拟在下游操作中很重要,因此我不能绕过此代码并只调用using块中的内容。可以将我的测试代码包装在WindowsIdentity.GetCurrent().Impersonate()中,然后然后调用using块内的内容(绕过MyService.svc.cs代码),但这样会少一些不太理想,因为它不是一个完整的端到端测试。

我不需要假冒不同的用户来冒充 - 我只需要在ServiceSecurityContext.Current中使用跑步者的用户上下文。

这可能吗?

1 个答案:

答案 0 :(得分:1)

我仍然对这种更好,更少侵入性的方式感兴趣,但这似乎现在有用。

我为MyService创建了第二个构造函数,允许使用WindowsIdentity.GetCurrent()

    private readonly bool _useLocalIdentity;

    public MyService(bool useLocalIdentity) :this()
    {
        _useLocalIdentity = useLocalIdentity;
    }


    private WindowsIdentity GetWindowsIdentity()
      {
        if (_useLocalIdentity)
        {
            return WindowsIdentity.GetCurrent();
        }

        var callerWinIdentity = ServiceSecurityContext.Current.WindowsIdentity;
        if (callerWinIdentity == null)
        {
            throw new InvalidOperationException("Caller not authenticated");
        }

        var cf = new ChannelFactory<IMyService>();
        cf.Credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;

        return callerWinIdentity;
    }