is it possible to assert whether a method has been called? I'm testing the following method and I want to assert that the _tokenManager.GetToken() has been called. I just want to know if the method has been called as the method does not return a value. I am using Moq.
Thanks,
Code snippet
public void Subscribe(string code, string emailAddress, string columnKey) { // Request authentication token var token = _tokenManager.GetToken(code, false); if (!_tokenValidator.Validate(token)) { // Token has expired or invalid - refresh the token token = _tokenManager.GetToken(code, true); } // Subscribe email _silverpopRepository.Subscribe(token.AccessToken, emailAddress, columnKey); }
2 Answers. Show activity on this post. Case 1: token is validated and GetToken is called exactly once. Case 2: token is not validated and GetToken is called exactly twice.
Apply a constraint to an actual value, succeeding if the constraint is satisfied and throwing an assertion exception on failure. Asserts that a condition is true. If the condition is false the method throws an AssertionException. Asserts that a condition is true.
Just like other classes can interact only with the public methods of your class, the same should apply to a unit test. The unit test should only test the public interface. Each private method is an implementation detail. They contain the logic necessary to implement a piece of functionality.
To ensure this, we use a technique called “mocking”. Mocking is a process where dependencies are replaced by controlled replacements that simulate the behavior of the real dependencies. NUnit is a unit testing framework for .
You should mock TokenManager
and TokenValidator
, and then create two unit test cases:
GetToken
is called exactly onceGetToken
is called exactly twiceCase 1:
[Test] public void Subscribe_TokenIsValidated_GetTokenIsCalledOnce() { // Arrange: var tokenManagerMock = Mock.Of<TokenManager>(); var tokenValidatorMock = Mock.Of<TokenValidator>(x => x.Validate(It.IsAny<Token>()) == true); var subscriber = new Subscriber { TokenManager = tokenManagerMock, TokenValidator = tokenValidatorMock }; // Act: subscriber.Subscribe(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()); // Assert: Mock.Get(tokenManagerMock).Verify(x => x.GetToken(It.IsAny<string>(), It.IsAny<bool>()), Times.Once); }
Case 2:
[Test] public void Subscribe_TokenIsExpiredOrInvalid_GetTokenIsCalledTwice() { // Arrange: var tokenManagerMock = Mock.Of<TokenManager>(); var tokenValidatorMock = Mock.Of<TokenValidator>(x => x.Validate(It.IsAny<Token>()) == false); var subscriber = new Subscriber { TokenManager = tokenManagerMock, TokenValidator = tokenValidatorMock }; // Act: subscriber.Subscribe(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()); // Assert: Mock.Get(tokenManagerMock).Verify(x => x.GetToken(It.IsAny<string>(), It.IsAny<bool>()), Times.Exactly(2)); }
Alternatively, you can create an unit test without mocking TokenValidator
and verify if GetToken()
has been called at least once. However, creating two cases as in the first example is preferred as we are testing all code paths.
// Arrange: var tokenManagerMock = Mock.Of<TokenManager>(); var subscriber = new Subscriber {TokenManager = tokenManagerMock}; // Act: subscriber.Subscribe(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()); // Assert: Mock.Get(tokenManagerMock).Verify(x => x.GetToken(It.IsAny<string>(), It.IsAny<bool>()), Times.AtLeastOnce);
Read more about verification in Moq at:
You can verify using MOQ using the Verify method. Like this:
var tokenManagerMock = new Mock<ITokenManager>(); var sut = new WhateverItIsCalled(tokenManagerMock.Object); sut.Subscribe("ssss", "[email protected]", "XXX"); tokenManagerMock.Verify(m => m.GetToken(It.Is<string>(c => c == "ssss", It.Is<bool>(x => x == false)), Times.Once);
You need to be able to pass the token manager into your system under test somehow. Usually via the ctor or maybe a property.
I would suggest you use something like AutoFixture to remove the ugliness that is "ssss" and make things a bit more DRY.
You may need to make the token manager mock return something appropriate too that will pass the validation. Something like this:
var tokenManagerMock = new Mock<ITokenManager>(); tokenManagerMock.Setup(m => m.GetToken(It.Is<string>(x => x == "ssss", It.IsAny<bool>()).Returns("XXXXXX");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With