C# Moq:当对象是模拟对象时,如何附加到该对象的委托属性?

C# Moq:当对象是模拟对象时,如何附加到该对象的委托属性?,c#,unit-testing,delegates,moq,C#,Unit Testing,Delegates,Moq,我有一个我想测试的对象,还有一个我正在模拟的依赖项。依赖项有一个公共委托属性,其功能基本上类似于事件。(我无法更改依赖项的代码。)如何模拟依赖项,然后触发其委托属性 我的情况: /* The thing I am mocking */ public interface IUserLoginReporter { public delegate void UserLoggedIn(string userName); UserLoggedIn OnUserLoggedIn { g

我有一个我想测试的对象,还有一个我正在模拟的依赖项。依赖项有一个公共委托属性,其功能基本上类似于
事件
。(我无法更改依赖项的代码。)如何模拟依赖项,然后触发其委托属性

我的情况:


/* 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 ...
}
[事实]
public void DelegateGetsInvoked()
{
//给定
var mockReporter=new Mock();
var userService=newuserservice(mockReporter.Object);
//什么时候
mockReporter.OnUserLoggedIn(“abc”);
//然后
//…验证userService采取了正确的操作。。。
}

理想情况下,如果接口像示例中描述的那样简单,那么最好只为测试创建一个简单的实现

但是,以下操作将允许调用委托,并调用测试主题中附加的委托

//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
//排列
var mock=new mock();
mock.SetupAllProperties();/\。OnUserLoggedIn);
//…断言预期行为

您试图断言的内容没有说明,因此这是否可能还有待观察。

在代码中显示您当前正在做的事情通过创建自己的“伪”实现开始-这将有助于理解,并且在许多情况下使测试比使用Mock更具可读性。谢谢,这很有效,似乎是预期的行为。看起来我的问题实际上不是关于嘲笑代表,而是关于嘲笑c#properties@PeterBeissinger更常见的情况是,当您获得空引用异常时,这是因为未设置某些内容。