【问题标题】:How to write a unit test for a method which calls other services如何为调用其他服务的方法编写单元测试
【发布时间】:2020-05-20 15:44:55
【问题描述】:

我有一个调用另一个服务的方法,但是在调用内部服务之前有一些数据操作。请看下文

   public async Task<myObject> Save(string server,string username, myObject element)
            {
                string temp = element.Class + "_" + element.Description + "_" + username;
                var saveData = new string[] { element.Name, temp};
                var response = await datService.save(server, saveData);
                var result = response.TomyObject(); // this is the extension method to convert response to myObject. 
                return result ;
            }

单元测试的最佳方式是什么? 我尝试了以下操作,但只是想确保我以“正确”的方式进行操作。

public async Task Save_Success()
        {
            //ARRANGE         
            var element = new myObject
            {
                Name = "Test",
                Description = "Test Save", 
                Class = "test class"


            };
            string temp = element.Class+ "_" + element.Description + "_" + username;
            var saveData = new string[] { element.Name, temp};
            var response = new anotherObject
            {

                Name= "Test",              
                MyArray = new objArray
                {
                    P0 = saveData[0],
                    P1 = saveData[1]                   

                },
                Error = ""

            };




            var datService = new Mock<IDataService>();
            datService.Setup(x => x.Save(It.IsAny<string>(), It.IsAny<string[]>()).Returns(Task.FromResult(response));
            var myClass = new MyClass(datService.Object);
            //ACT
            var result = await myClass.Save("testServer","testUser", element);
            // ASSERT
            Assert.AreEqual(response.MyArray.P0, result.Class);
        }

这里是扩展方法

 public static myObject TomyObject(this anotherObject response)
        {
            var entity = new myObject();

            entity.Name = response.Name;           
           if(response.MyArray!= null && response.MyArray.P1 != "")
            {
                string[] details = response.MyArray.P1.Split('_');
                entity.Class = details[0];
                entity.Description = details[1];


            }

            return entity;

        }

【问题讨论】:

  • 如果原始方法调用datService.save,为什么要存根datService,Execute
  • 抱歉,打错字了。我更改了这篇文章的名称。我修好了。
  • 我的主要困惑是由于扩展方法,我是否安排了 dataService 的响应,所以我的扩展方法给了我期望的结果(就像我在测试中所做的那样)或者还有另一种方法可以做到这一点?
  • 什么扩展方法?在代码中找不到任何 C# 扩展。

标签: c# unit-testing moq mstest


【解决方案1】:

以下是测试扩展方法的方法:

anotherObject response = new anotherObject
{
    Name = "TestName",
    MyArray = new objArray
    {
        P1 = "Val1_Val2"
    }
};
var result = response.TomyObject();
Assert.Equal("TestName", result.Name);
Assert.Equal("Val1", result.Class);
Assert.Equal("Val2", result.Description);

关键是让您的单元测试只测试一个工作单元。如果您想测试您的扩展方法,请为它单独编写一个测试。一旦你开始包含多个工作单元(即IDataService),你实际上是在测试一个系统,它变成了一个集成测试。

更新:

在您的Save_Success 测试中的这一行:

// ASSERT
Assert.AreEqual(response.MyArray.P0, result.Class);

您实际上是在测试不是Save 方法的职责(设置Class 属性实际上是您的TomyObject 的职责,可以单独测试)。

要验证Save 方法是否在做它应该做的事情,你可以这样做:

// ASSERT
datService.Verify(x => x.Save(It.IsAny<string>(), It.IsAny<string[]>()), Times.Once);

这样,您只是在测试 Save 方法是否正在执行它明确负责的操作。

【讨论】:

  • 那么我做单元测试的方式是正确的吗?我可以安排 IDataService 对我的预期结果的响应吗?然后对 Extension 方法进行不同的单元测试?
  • @user2918107 我在答案中添加了一些额外的信息。希望这会有所帮助
  • 非常感谢,这就是我要找的。​​span>
猜你喜欢
  • 2016-01-19
  • 1970-01-01
  • 2019-09-25
  • 2011-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多