Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 对某些方法的检查调用应属于单元测试_C#_Asp.net_Unit Testing - Fatal编程技术网

C# 对某些方法的检查调用应属于单元测试

C# 对某些方法的检查调用应属于单元测试,c#,asp.net,unit-testing,C#,Asp.net,Unit Testing,我试图遵循一种测试行为而不是一种方法(这是我最初所做的)。就像我正在测试从服务器刷新项目的功能一样 它基本上是通过刷新项()方法完成的。在这个方法中,我对其他服务的其他方法进行了一些调用,比如说NetworkService(用于web请求) 因为RefreshItems的实现可能会更改,或者它可能不会调用NetworkService的某些特定方法 因此,我的单元测试是否应该包括一个测试来检查是否调用了NetworkService方法?我会检查是否已经进行了所有必要的调用。测试RefreshIte

我试图遵循一种测试行为而不是一种方法(这是我最初所做的)。就像我正在测试从服务器刷新项目的功能一样

它基本上是通过刷新项()方法完成的。在这个方法中,我对其他服务的其他方法进行了一些调用,比如说NetworkService(用于web请求)

因为RefreshItems的实现可能会更改,或者它可能不会调用NetworkService的某些特定方法


因此,我的单元测试是否应该包括一个测试来检查是否调用了NetworkService方法?

我会检查是否已经进行了所有必要的调用。测试RefreshItems时,模拟相关服务(如NetworkService)并验证是否已进行调用

编辑:

假设您有这样一个MyService的接口和实现

public interface IMyService
{
    IEnumerable<string> Get();
    void SuperImportantMethod();
}

public class MyService : IMyService
{
    public IEnumerable<string> Get()
    {
        SuperImportantMethod();
        return new string[] { string.Empty };
    }

    public virtual void SuperImportantMethod()
    {
        // and secret!
    }
}
在测试MyService时,您可以确保每次服务“获取”某些内容时都调用
SuperImportantMethod

[TestClass]
public class MyServiceTests
{
    [TestMethod]
    public void GetTest()
    {
        var mock = new Mock<MyService>();
        var service = mock.Object;

        service.Get();
        mock.Verify(s => s.SuperImportantMethod(), Times.Once);
    }
}
[TestClass]
公共类MyServiceTests
{
[测试方法]
公共无效GetTest()
{
var mock=new mock();
var service=mock.Object;
service.Get();
mock.Verify(s=>s.superportantmethod(),Times.Once);
}
}

网络服务注入接口。它可以称为
INetworkService
,但
IItemsService
可能会:

public interface IItemsService
{
    Items GetAllItems(); //or whatever you need
}
那么您有两个选择:

模拟和验证

为该接口注入一个mock并验证调用了正确的调用,但正如您所说的,这将测试实现而不是行为

var itemsService = new Mock<IItemsService>(); //Moq for example
var testObject = new ClassUnderTest(itemsService.Object);
testObject.RefreshItems();
itemsService.Verify(e => e.GetAllItems(), Times.Once); //verify the calls to the moq
请注意,您也可以使用Moq进行存根,而不是创建存根类:

var itemsService = new Mock<IItemsService>();
itemsService.Setup(e => e.GetItems()).Returns(/*whatever*/);
var testObject = new ClassUnderTest(itemsService.Object);
testObject.RefreshItems();
Assert.AreEqual(1, testObject.Items); //some assert on the testObject
var itemsService=new Mock();
itemsService.Setup(e=>e.GetItems())。返回(/*whatever*/);
var testObject=newclassundertest(itemsService.Object);
testObject.RefreshItems();
AreEqual(1,testObject.Items)//一些在testObject上断言

单元测试不应该是这样的-我们应该测试行为而不是实现。可能会发生这样的情况,我们必须改变制冷剂的实施,然后在这种情况下,一切都会破裂。我们将测试对某个方法的调用,该方法最终不存在于新的IMementation中。如果您可以隔离RefreshItems(),并且确实不需要知道NetworkService是否调用了某个方法,那么您当然会忽略它。我用示例修改了我的答案。我的问题是-我的UnitTests是否应该包括一个单独的测试来检查是否调用了NetworkService方法?你这样问是因为它是网络服务吗。i、 如果它只是另一个类,你会问这个吗?不,它可以是任何类,或者其他方法。我的问题是关于单元测试方法的。我会写单元测试。说够了,展示代码
var itemsService = new Mock<IItemsService>(); //Moq for example
var testObject = new ClassUnderTest(itemsService.Object);
testObject.RefreshItems();
itemsService.Verify(e => e.GetAllItems(), Times.Once); //verify the calls to the moq
var itemsService = new StubItemsService();
var testObject = new ClassUnderTest(itemsService);
testObject.RefreshItems();
Assert.AreEqual(1, testObject.Items); //some assert on the testObject
var itemsService = new Mock<IItemsService>();
itemsService.Setup(e => e.GetItems()).Returns(/*whatever*/);
var testObject = new ClassUnderTest(itemsService.Object);
testObject.RefreshItems();
Assert.AreEqual(1, testObject.Items); //some assert on the testObject