我试图跟踪测试行为而不是方法(这是我最初在做的事情)。就像我正在测试我从服务器刷新项目的功能。
基本上是在 RefreshItems ()方法中完成的。在这种方法中,我可以调用其他服务的其他方法,比如你可以说 NetworkService (用于网络请求)。
由于RefreshItems的实现可能会发生变化,或者它可能没有调用NetworkService的某些特定方法。
我的 UnitTests 是否应包含测试以检查是否已调用NetworkService方法?
答案 0 :(得分:0)
我会检查是否已拨打所有必要的电话。在测试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!
}
}
然后使用此服务的MyClass,如:
public class MyClass
{
public MyClass()
{}
public MyClass(IMyService service)
{
Service = service;
}
public void RefreshItems()
{
Items = Service.Get();
}
public IMyService Service { get; set; }
public IEnumerable<string> Items { get; set; }
}
然后,您可以测试与服务隔离的MyClass RefreshItems
方法。
[TestMethod]
public void RefreshItemsTest()
{
var expected = new string[] {"my", "items", "here"};
var myClass = new MyClass();
var mock = new Mock<IMyService>();
mock.Setup(service => service.Get()).Returns(expected);
myClass.Service = mock.Object;
myClass.RefreshItems();
Assert.IsTrue(expected.SequenceEqual(myClass.Items));
}
在测试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);
}
}
答案 1 :(得分:0)
为NetworkService
注入界面。它可以被称为INetworkService
,但IItemsService
可能会出现问题:
public interface IItemsService
{
Items GetAllItems(); //or whatever you need
}
然后你有两个选择:
模拟并验证
为该接口注入一个模拟并验证是否调用了正确的调用,但正如您所说,这将测试实现而不是行为。
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
<强>存根强>
创建一个返回固定数据的IItemsService
的Stub实现。然后Assert
您正在测试的班级的新状态。
var itemsService = new StubItemsService();
var testObject = new ClassUnderTest(itemsService);
testObject.RefreshItems();
Assert.AreEqual(1, testObject.Items); //some assert on the testObject
请注意,您也可以使用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