2015-06-29 143 views
1

运行Web服务我创建的验证一些规则的功能。每当列表的一个元素与另一个列表的元素相匹配时,函数应该返回一个布尔值。如何在单元测试

这里是规则类

public override TestResult Execute() 
{ 
     Instrument ins = (Items.Length > 0) ? Items[0] as Instrument : null; 
     string errorInfo; 

     if (ins == null) 
     { 
      Result.Message = "Unable to perform test"; 
      Result.Status = ResultStatus.Error; 
      return Result; 
     } 
     if (MPICSupportDB(ins)) 
     { 
      Result.Message = "DB not supported by MPIC"; 
      Result.Status = ResultStatus.Yellow; 
     } 
     else 
     { 
      Result.Status = ResultStatus.Green; 
     } 

     return Result; 
} 

private bool MPICSupportDB(Instrument ins) 
{ 
    IServiceProviderFactory serviceFactory = new WebServiceProviderFactory(); 
    IInterfaceAssignmentService wService = serviceFactory.CreateInterfaceAssignmentService(); 
    InterfaceAssignment wAssignments = wService.LoadAssignmentGroup("R4"); 

    return ins.Connections.OfType<InterfaceConnection>() 
          .Where(conn => conn.Card.IsDB) 
          .Any(conn => wAssignments.PartMasters 
          .Any(partNumber => (conn.CardPartNumber == partNumber.PartNumber)));    
} 

我试图测试功能MPICSupportDB在单元测试的相关代码。到目前为止,我已经开始创建我的单元测试(下面),但现在我迷路了,我不知道该怎么做。

[TestMethod] 
public void TestForcompatibleDB() 
{ 
    var ins = new Instrument(); 
    var serviceFactoryMock = new Mock<IServiceProviderFactory>(); 
    var wserviceTest = new Mock<IInterfaceAssignmentService>(); 
    var wassagnementTest = new Mock<InterfaceAssignment>(); 

    // adding an MPIC card 
    ins.Connections.Add(AddCard(CardType.MPIC, "MA505400612268", "CARD1", 0, ins)); 

    // adding an MPIC daughterboard 
    ins.Connections.Add(AddCard(CardType.GPIM_DB, "MA335022012268", "DB1", 1, ins)); 


    var rule = new Rule026(RuleApplicability.Test, new object[] { ins }); 
    var result = rule.Execute(); 

    Assert.IsNotNull(result); 
    Assert.AreEqual(ResultStatus.Green, result.Status); 

} 

的问题是,像WebservicefactoryService类不能直接在单元测试运行。

有人能向我解释如何正确地嘲笑这些对象,让我试运行?

回答

0

您需要提供IServiceProviderFactoryRule026类,而不是在类的内部构造吧。这将允许你使用你正在创建的Mocks。最常见的方法是通过构造函数注入。您还没有提供为您的规则类的构造函数,但如果你将它修改为这样的事情:

public Rule026(/*otherArgs*/, IServiceProviderFactory scpFactory = null) { 
    if(null == scpFactory) 
     scpFactory = new ServiceProviderFactory(); 
    } 
    _serviceProviderFactory = scpFactory; 
} 

然后,你就可以从你的测试中注入的工厂,而不必更新所有的目前构建规则的代码。移动到IOC容器提供的依赖,或删除默认和强制客户端,以便能够实例规则可能是可取的,根据您的情况来创建工厂。

一旦你可以通过你的嘲笑,你只需要设置一个返回链,让嘲笑相互回报。喜欢的东西:

var serviceFactoryMock = new Mock<IServiceProviderFactory>(); 
    var wserviceTest = new Mock<IInterfaceAssignmentService>(); 
    var wassagnementTest = new Mock<InterfaceAssignment>(); 

    serviceFactoryMock.Setup(x=>x.CreateInterfaceAssignmentService()) 
         .Returns(wserviceTest.Object); 
    wserviceTest.Setup(x=>x.CreateInterfaceAssignmentService()) 
       .Returns(wassagnementTest.Object); 
    wassagnementTest.Setup(x=>x.LoadAssignmentGroup(It.IsAny<string>())) 
       .Returns(cannedInterfaceAssignmentResponse); 

然后构造你的对象时提供的模拟:

var rule = new Rule026(RuleApplicability.Test, 
         new object[] { ins }, 
         serviceFactoryMock.Object); 

您可能还需要验证等添加到您的嘲弄,这取决于你想测试和你的特殊的测试风格。

+0

谢谢你,非常喜欢,我会尝试了这一点.....谢谢你的灵感 – napi15