简体   繁体   中英

Moq: How to attach to a delegate property of an object, when that object is a mock?

I have an object I want to test, and a dependency for it which I am mocking. The dependency has a public delegate property which functions essentially like an event . (I cannot change the code of the dependency.) How do I mock the dependency, then trigger its delegate property?

My situation:


/* 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)
   {
       ...
   }
}

As you can see, the UserLoginReporter has a delegate property which it will invoke when the user logs in. The UserService attaches its RefreshLastSeenTime to this delegate, so we take some actions in response.

Here is essentially the test I wrote:

[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 ...
}

I am getting a null-reference exception on the line just under // When .

Ideally if the interface is as simple as described in your example, you are better off just creating a simple implementation for your test.

However, the following will allow the delegate to be invoked and call the attached delegate within the subject under test

//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

What you are trying to assert was not stated so whether that is possible is left to be seen.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM