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