2014-05-05 42 views
3

我嘗試測試繼承基類Hub(implements IHub interface)的自定義RepositoryHub。我嘲笑IHub的所有必要屬性,以及我想測試的一個方法調用。方法調用被模仿爲來自派生自定義類的調用RepositoyHub:
hubMock.Setup(p => p.OnConnected()).Returns(new RepositoryHub().OnConnected());
問題是該方法無法訪問模擬的IHub字段。SignalR:使用moq框架模擬IHub並測試他的方法

[TestMethod] 
    public void Is_OnConnected_Successive_When_Instances_is_Absent_And_User_Authenticated() 
    { 
     try 
     { 
      var connectionId = "1"; 

      var request = new Mock<IRequest>(); 
      request.Setup(s => s.User.Identity.Name).Returns(user + "&" + server + "&" + password + "&" + level); 
      request.Setup(s => s.User.Identity.IsAuthenticated).Returns(true); 

      var mockClients = new Mock<IHubCallerConnectionContext>(); 
      var mockGroupManager = new Mock<IGroupManager>(); 
      var mockHubCallerContext = new Mock<HubCallerContext>(request.Object, connectionId); 

      var hubMock = new Mock<IHub>(); 
      hubMock.Setup(p => p.Groups).Returns(mockGroupManager.Object); 
      hubMock.Setup(p => p.Context).Returns(mockHubCallerContext.Object); 
      hubMock.Setup(p => p.Clients).Returns(mockClients.Object); 
      //Mock virtual method call 
      hubMock.Setup(p => p.OnConnected()).Returns(new RepositoryHub().OnConnected()); 


      var r = hubMock.Object.OnConnected(); 
     } 
     catch (Exception ex) 
     {  
      throw; 
     } 
    } 
     // Here method which i want to test with mocked IGroupManager, HubCallerContext and IHubCallerConnectionContext 

    public partial class RepositoryHub: Hub 
    { 
     public override Task OnConnected() 
     { 
      try 
      { 
       var userProfile = new UserProfile(Context.User); 
       //NullReference exception Context == null, but why i got it if mocked 
       //HubCallerContext in test method 

       Groups.Add(Context.ConnectionId, userProfile.ServerUrl); 
       // and other useful actions 

       return base.OnConnected(); 
      } 
      catch (Exception ex) 
      { 
       Log.TraceError(String.Format(" Hub: OnConnected() {0}", ex.Message)); 
       throw; 
      } 
     } 
    } 

回答

7


我想出了簡單的方法,對我來說。感謝您的關注!

  var repository = new RepositoryHub(){ Context = mockHubCallerContext.Object, 
                Clients = mockClients.Object, 
                Groups = mockGroupManager.Object }; 

      var r = repository.OnConnected(); 

對於JohnB,回答你的最後一個問題:

[TestMethod] 
public void Is_OnConnected_Successive() 
{ 
    const string connectionId = "1"; 
    dynamic groupName = new ExpandoObject(); 

    var IsSendMessageCalled = false; 

    groupName.sendMessage = new Action<object>((message) => 
    { 
     IsSendMessageCalled = true; 
     Debug.WriteLine("sendMessage was called, message: {0}", message); 
    }); 

    var request = new Mock<IRequest>(); 
    request.Setup(s => s.User.Identity.Name).Returns(user + "&" + server + "&" + password + "&" + level); 
    request.Setup(s => s.User.Identity.IsAuthenticated).Returns(true); 

    var mockClients = new Mock<IHubCallerConnectionContext>(); 
    mockClients.Setup(m => m.Group("groupName")).Returns((ExpandoObject)groupName); 

    var mockGroupManager = new Mock<IGroupManager>(); 
    var mockHubCallerContext = new Mock<HubCallerContext>(request.Object, connectionId); 

    var hub = new RepositoryHub() 
    { 
     Context = mockHubCallerContext.Object, 
     Clients = mockClients.Object, 
     Groups = mockGroupManager.Object 
    }; 

    var testMethod = hub.OnConnected(); 
    Thread.Sleep(threadSleepTime); 
    //or testMethod.Wait(); 

    Assert.IsTrue(IsSendMessageCalled); 
} 

讓我們建議,在這裏你打電話給你的sendMessage(消息)方法:

public override Task OnConnected() 
{ 
    Hub.Clients.Group("groupName").sendMessage("Hello ! for groupName group "); 
} 
+0

你好:我發現您的文章和回答非常有啓發性。我遇到了一個額外的問題。我遵循你的模式。我有困難從我的嘲弄小組發送消息。因此,以下調用:Clients.Group(groupName).sendMessage(message)失敗,因爲Clients.Group()調用返回null。你有沒有遇到這個問題或者有什麼想法如何解決這個問題?謝謝! – JohnB

+0

@JohnB你好!是的,我做到了。我在 – Ark

+0

之上添加了針對您的問題的答案感謝您的其他信息。這絕對有用。我發現自己希望SignalR庫本身更加開放,這樣我就可以在單元測試期間直接查看客戶和組的集合以進行調查。我希望能夠建立一個涉及多個集線器和客戶的單元測試。你有什麼經驗嗎?我會寫一個新的職位重新評估。再次感謝! – JohnB