Moq:当对象是模拟对象时,如何附加到对象的委托 属性?
Moq: How to attach to a delegate property of an object, when that object is a mock?
我有一个要测试的对象,以及我正在模拟的它的依赖项。该依赖项有一个 public 委托 属性,其功能本质上类似于 event
。 (我无法更改依赖项的代码。)如何模拟依赖项,然后触发其委托 属性?
我的情况:
/* The thing I am mocking */
public interface IUserLoginReporter {
public delegate void UserLoggedIn(string userName);
UserLoggedIn OnUserLoggedIn { get; set; }
}
/* The thing I am testing */
public class UserService {
public UserService(IUserLoginReporter reporter)
{
reporter.OnUserLoggedIn += RefreshLastSeenTime;
}
public void RefreshLastSeenTime(string username)
{
...
}
}
如您所见,UserLoginReporter 有一个委托 属性,它将在用户登录时调用。UserService 将其 RefreshLastSeenTime 附加到该委托,因此我们采取一些响应措施。
这里基本上是我写的测试:
[Fact]
public void DelegateGetsInvoked()
{
// Given
var mockReporter = new Mock<IUserLoginReporter>();
var userService = new UserService(mockReporter.Object);
// When
mockReporter.OnUserLoggedIn("abc");
// Then
// ... verify userService took correct actions ...
}
我在 // When
.
正下方的行中收到空引用异常
理想情况下,如果接口像您的示例中描述的那样简单,您最好只为您的测试创建一个简单的实现。
但是,以下将允许调用委托并在测试对象中调用附加的委托
//Arrange
var mock = new Mock<IUserLoginReporter>();
mock.SetupAllProperties(); //<--Automatically allow properties to be modifiable
UserService subject = new UserService(mock.Object);
string input = "I am working";
//Act
mock.Object.OnUserLoggedIn(input);
//Assert
mock.Verify(_ => _.OnUserLoggedIn);
//...assert expected behavior
您试图断言的内容并未说明,因此是否可行还有待观察。
我有一个要测试的对象,以及我正在模拟的它的依赖项。该依赖项有一个 public 委托 属性,其功能本质上类似于 event
。 (我无法更改依赖项的代码。)如何模拟依赖项,然后触发其委托 属性?
我的情况:
/* The thing I am mocking */
public interface IUserLoginReporter {
public delegate void UserLoggedIn(string userName);
UserLoggedIn OnUserLoggedIn { get; set; }
}
/* The thing I am testing */
public class UserService {
public UserService(IUserLoginReporter reporter)
{
reporter.OnUserLoggedIn += RefreshLastSeenTime;
}
public void RefreshLastSeenTime(string username)
{
...
}
}
如您所见,UserLoginReporter 有一个委托 属性,它将在用户登录时调用。UserService 将其 RefreshLastSeenTime 附加到该委托,因此我们采取一些响应措施。
这里基本上是我写的测试:
[Fact]
public void DelegateGetsInvoked()
{
// Given
var mockReporter = new Mock<IUserLoginReporter>();
var userService = new UserService(mockReporter.Object);
// When
mockReporter.OnUserLoggedIn("abc");
// Then
// ... verify userService took correct actions ...
}
我在 // When
.
理想情况下,如果接口像您的示例中描述的那样简单,您最好只为您的测试创建一个简单的实现。
但是,以下将允许调用委托并在测试对象中调用附加的委托
//Arrange
var mock = new Mock<IUserLoginReporter>();
mock.SetupAllProperties(); //<--Automatically allow properties to be modifiable
UserService subject = new UserService(mock.Object);
string input = "I am working";
//Act
mock.Object.OnUserLoggedIn(input);
//Assert
mock.Verify(_ => _.OnUserLoggedIn);
//...assert expected behavior
您试图断言的内容并未说明,因此是否可行还有待观察。