简体   繁体   English

模拟 - 虽然 setup.Returns(true) 但总是得到 false

[英]Mock - Although setup .Returns(true) but always get false

I have code snippet as following.我有如下代码片段。 Although setup with retrurn true but value always return false.虽然设置返回 true 但值总是返回 false。

Could someone advise how to retrieve value as true?有人可以建议如何将价值检索为真吗?

public interface IDatabaseService
  {
    bool ProcessSQL(INApplicationProcessDTO inApplicationProcessDTO, string connectionString, string storedProcedureName);
    bool CompleteRun(INApplicationProcessDTO inApplicationProcessDTO, string connectionString, string storedProcedureName);
  }

----CLASS---------- - - 班级 - - - - -

public static class INHelper
{
    public static bool CompleteRun(INApplicationProcessDTO inApplicationProcessDTO, string connectionString = null, IDatabaseService databaseService = null)
    {
      if (inApplicationProcessDTO == null)
      {
        return false;
      }
      if (inApplicationProcessDTO.Data == null)
      {
        return false;
      }
      const string storedProcedureName = "PSP_PWS_INApplication_Application_Process_CompleteRun";

      // Get Connection String to Parity4 Database from Parity4 WebService Web.config
      if (connectionString == null)
      {
        if (ConfigurationManager.ConnectionStrings["ConnectionString"] != null)
        {
          connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
        }
      }
      if (string.IsNullOrWhiteSpace(connectionString))
      {
        return false;
      }

      if (databaseService == null)
      {
        databaseService = new DatabaseService();
      }
      //Why always return false line below
      return databaseService.CompleteRun(inApplicationProcessDTO, connectionString, storedProcedureName);
    }
}

----TEST METHOD---- - - 测试方法 - -

public void When_CompleteRun_ConnectionValid_Expect_True()
    {
      var iNApplicationProcessDTOTest = new INApplicationProcessDTO()
      {
        Data = new System.Xml.Linq.XDocument(),
        ErrorCount = 0,
        Errors = ""
      };

      Mock<IDatabaseService> iDatabaseService = null;
      iDatabaseService = new Mock<IDatabaseService>();
      iDatabaseService.Setup(t => t.CompleteRun(iNApplicationProcessDTOTest, "test", "test")).Returns(true);
      iDatabaseService.Setup(t => t.ProcessSQL(iNApplicationProcessDTOTest, "test", "test")).Returns(true);

      var iNApplicationProcessDTO = new INApplicationProcessDTO()
      {
        Data = new System.Xml.Linq.XDocument(),
        ErrorCount = 0,
        Errors = ""
      };
      var actual = INHelper.CompleteRun(iNApplicationProcessDTO, "a", iDatabaseService.Object);
      //actual always false although Returns(true) in Setup
      Assert.AreEqual(true, actual);
    }        

Appreciate your help.感谢你的帮助。

There are a couple of tiny problems with your Test code.您的测试代码有几个小问题。

First let me show how you should implement it and then let me give you some explanation:首先让我展示你应该如何实现它,然后让我给你一些解释:

[Fact]
public void GivenAFlawlessDatabaseService_WhenICallCompleteRun_ThenItCallsTheUnderlyingServicesCompleteRun()
{
    //Arrange
    const string connectionString = "a";
    var iDatabaseService = new Mock<IDatabaseService>();

    iDatabaseService
        .Setup(db => db.CompleteRun(It.IsAny<INApplicationProcessDTO>(), It.IsAny<string>(), It.IsAny<string>()))
        .Returns(true);

    var iNApplicationProcessDTO = new INApplicationProcessDTO
    {
        Data = new XDocument(),
        ErrorCount = 0,
        Errors = ""
    };

    //Act
    var actual = INHelper.CompleteRun(iNApplicationProcessDTO, connectionString, iDatabaseService.Object);
    
    //Assert
    Assert.True(actual);
    iDatabaseService.Verify(db => db.CompleteRun(iNApplicationProcessDTO, connectionString, "PSP_PWS_INApplication_Application_Process_CompleteRun"), Times.Once);
    iDatabaseService.Verify(db => db.ProcessSQL(It.IsAny<INApplicationProcessDTO>(), It.IsAny<string>(), It.IsAny<string>()), Times.Never);
}
  • First, I would suggest to use somewhat more meaningful names for your tests.首先,我建议为您的测试使用更有意义的名称。 Here I've used a Given When Then structure to describe under what circumstances (given) if a specific action is triggered (when) what would I expect (then)在这里,我使用 Given When Then 结构来描述在什么情况下(给定)如果触发特定操作(何时)我会期望什么(然后)
  • I also suggest to use the Arrange , Act and Assert comments to separate different phases of your test case visually我还建议使用ArrangeActAssert注释来直观地分隔测试用例的不同阶段
  • The Setup method calls normally do not rely on concrete objects. Setup方法调用通常不依赖于具体对象。 The reason behind it is that classes are compared by reference.其背后的原因是类是通过引用进行比较的。 So, even if you have two seemingly identical instances (like: iNApplicationProcessDTOTest and iNApplicationProcessDTO ) they are different.因此,即使您有两个看似相同的实例(例如: iNApplicationProcessDTOTestiNApplicationProcessDTO ),它们也是不同的。 That's why the mock function is not being called.这就是为什么不调用模拟 function 的原因。
    • Use It.IsAny<T>() calls in the Setup phase and use concrete values in the Verify phase.Setup阶段使用It.IsAny<T>()调用,并在Verify阶段使用具体值。
  • If one of the methods of the mocked object is not called by the SUT (system under test) then you don't need to Setup it.如果模拟的 object 的方法之一没有被 SUT(被测系统)调用,那么您不需要Setup它。
    • But you can still verify that it has not been called ( Verify(..., Times.Never); )但是你仍然可以验证它没有被调用( Verify(..., Times.Never);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM