I have become slightly stumped. I'm Unit Testing my ServicesController where I call different methods such as:
GetRoles()
GetDomains()
GetUsers()
In my Unit Test I have checked that the call is being made and is being run properly and that is all fine. However I want to make an Assert/call where I can check that this method is returning X amount of users from my mocked _userList where they are enabled.
The following code is my GetUsers() method:
[CustomAuthorize]
public ActionResult GetUsers(bool enabledOnly = true)
{
return new JsonNetResult { Data = _authorizationLoader.GetUsers(enabledOnly) };
}
I would like to know how to get this to return users from my _userList that are enabled and to be able to Assert the correct amount are called at the end of the test.
This part of my code is the unit test for the method:
private User _user1;
private User _user2;
private User _user3;
private User _user4;
private User _user5;
private bool isEnabled;
private List<User> _userList;
private Mock<IAuthorizationLoader> iAuthLoaderMock;
public override void SetUp()
{
_user1 = new User
{
stuff needed is here
};
_user2 = new User
{
stuff needed is here
};
_user3 = new User
{
stuff needed is here
};
_user4 = new User
{
stuff needed is here
};
_user5 = new User
{
stuff needed is here
};
_userList = new List<User>();
_userList.Add(_user1);
_userList.Add(_user2);
_userList.Add(_user3);
_userList.Add(_user4);
_userList.Add(_user5);
isEnabled = true;
}
public override void Initialize()
{
iAuthLoaderMock = MockContainer.GetMock<IAuthorizationLoader>();
iAuthLoaderMock.Setup(i => i.GetUsers(isEnabled)).Verifiable();
base.Initialize(); // dont worry about this call it is needed though
}
public override void Because()
{
TestSubject.GetUsers(true);
// this subject is created in code above but is unecessary to include
}
[TestMethod]
public void The_controller_returns_only_enabled_users()
{
iAuthLoaderMock.Verify(i => i.GetUsers(isEnabled));
//---------------- Need to find a way of returning and checking this -------------------------//
//Assert.AreEqual(X (number of enabled users), new _userList.result(my result from test));
}
any help would be great as this has me stumped. Thanks.
Related
I'm trying to mock the DateTime.UtcNow in a unit test, using Pose, but it seems that is not working in .NET 6.
The code looks like this:
// Arrange
...
var created = DateTime.UtcNow;
var expectedRequest = new ExpectedRequest()
{
Created = created
...
};
var shim = Shim.Replace(() => DateTime.UtcNow).With(() => created);
PoseContext.Isolate(() =>
{
// Act
var mappedRequest = request.ToExpectedRequest();
// Assert
mappedRequest.Should().BeEquivalentTo(expectedRequest);
}, shim);
...
The problem is that the unit test is stuck when PoseContext.Isolate(() is reached and when I try to stop the unit test, Visual Studio freezes and restarts itself.
Is there any other option or library similar to Pose?
I know that the most common approach is to introduce an interface that the application logic will use instead of the direct use of DateTime.UtcNow property, but I don't want to inject a new service just for that and I'm trying to find a solution without modifying the implementation.
Edit:
There are multiple ways to 'solve' this mocking problem for DateTime that can be found here or here, but I choose the Ambient Context approach.
The unit test looks like this now:
// Arrange
...
using var context = new DateTimeProviderContext(DateTime.UtcNow);
var expectedRequest = new ExpectedRequest()
{
Created = DateTimeProvider.UtcNow
...
};
// Act
var mappedRequest = request.ToExpectedRequest();
// Assert
mappedRequest.Should().BeEquivalentTo(expectedRequest);
...
In the implementation the only thing left to do was to use Created = DateTimeProvider.UtcNow instead of Created = DateTime.UtcNow.
I will add here those 2 classes DateTimeProvider and DateTimeProviderContext in case someone needs them.
public static class DateTimeProvider
{
public static DateTime Now
=> DateTimeProviderContext.Current == null
? DateTime.Now
: DateTimeProviderContext.Current.ContextDateTime;
public static DateTime UtcNow => Now.ToUniversalTime();
}
public class DateTimeProviderContext : IDisposable
{
internal DateTime ContextDateTime;
private static readonly ThreadLocal<Stack> _threadScopeStack = new(() => new Stack());
private bool _isDisposed = false;
public DateTimeProviderContext(DateTime contextDateTime)
{
ContextDateTime = contextDateTime;
_threadScopeStack.Value?.Push(this);
}
public static DateTimeProviderContext? Current
{
get
{
if (_threadScopeStack.Value?.Count == 0)
{
return null;
}
else
{
return _threadScopeStack.Value?.Peek() as DateTimeProviderContext;
}
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_isDisposed && disposing)
{
_threadScopeStack.Value?.Pop();
}
_isDisposed = true;
}
}
I have a class that I am trying to test out through writing some unit test in C#. I am also using Moq library in my unit test for mocking.
Below are some of the methods in my class which I want to mock so that they can return some dummy data which I want to return always.
public class DataManager
{
public DataManager(ILoggingService loggingService, IConfiguration configuration)
{
// ...
}
// how to mock this to return dummy data?
private DataHolder GetData()
{
//... return DataHolder object
}
// how to mock this to return dummy data?
private IEnumerable<ProcessClient> GetClientValues(string value)
{
//... return IEnumerable<ProcessClient> object
}
}
This is how I am testing it out:
private Mock<ClientUtility> utility;
[SetUp]
public void Setup()
{
utility = new Mock<ClientUtility>();
}
[Test]
public void Test1()
{
// what should I do here so that "GetData" and "GetClientValues" return dummy data when I call below class constructor?
var testName = "config1";
var testContent = "{}";
utility.Setup(x => x.Add(new DataStatus { Pin = "test" }, "data.com", "test")).Returns(Task.FromResult(true));
var dataManager = new DataManager(loggingService.Object, configuration.Object);
Assert.AreEqual(testContent, dataManager.GetStuff(testName)[0]);
}
Question:
How can I mock "GetData" and "GetClientValues" using Moq or any other library to return dummy data from those two methods? Is this possible to do?
I think you can use CallBase = true.
So your mock will behave like true class.
var dataManager = new Mock<DataManager>(loggingService.Object, configuration.Object) { CallBase = true };
dataManager.Object.Method1();
dataManager.Object.Method2();
And you can mock some methods like you do with utility.
Search by "CallBase" on page:
https://github.com/Moq/moq4/wiki/Quickstart
UPDATE
I made methods public to call them.
And there is some issue, that i didn't see last time. You need to make "virtual" methods if you want change their behavior.
There is example of code. As you can see, GetClientValues() returns real data because we call default real implementation with CallBase = true and GetData() returns dummy data because we mocked its behavior.
public class DataManager
{
public DataManager(ILoggingService loggingService, IConfiguration configuration)
{
// ...
}
// how to mock this to return dummy data?
public virtual DataHolder GetData()
{
return new DataHolder
{
Data = "RealData"
};
}
// how to mock this to return dummy data?
public IEnumerable<ProcessClient> GetClientValues(string value)
{
return new List<ProcessClient>
{
new ProcessClient
{
Data = "RealData"
}
};
}
}
And tests.
public class Tests
{
[SetUp]
public void Setup()
{
}
[Test]
public void Test1()
{
var loggingService = new Mock<ILoggingService>();
var config = new Mock<IConfiguration>();
var dataManager = new Mock<DataManager>(loggingService.Object, config.Object){CallBase = true};
dataManager.Setup(x => x.GetData()).Returns(new DataHolder { Data = "FakeData" });
Assert.AreEqual("RealData", dataManager.Object.GetClientValues("test").First().Data);
Assert.AreEqual("FakeData", dataManager.Object.GetData().Data);
}
}
But anyway i think, that this approach isn't good for testing.
There is a problem with testing private methods. We have some ways (for example Invoke()), but in general, "if you want to unit test a private method, something may be wrong". I would like to recommend you to read something about test design and writing testable code.
About testing private methods How do you unit test private methods?.
I have a class, like this one:
public class SomeClass: ISomeClass
{
public async Task<ServiceResponse> PerformAction(Context context)
{
if(IsPartner(context))
{
SendTextMessageAsync(context);
}
}
public bool IsPartner(Context context)
{
return SomeStaticHelperClass.GetIsPartner(context.PartnerId);
}
public async void SendTextMessageAsync(Context context)
{
// sends the message
}
}
ISomeClass exposes all three methods.
I'm using Moq and I would like to write a test that verifies
when IsPartner returns true
then SendTextMessage is called once.
I've tried everything I can think of.
This is my latest attempt:
public class ReceiptServiceTests
{
[Fact]
public async void SendReceiptsProofsNeededNudgeAsync_ShouldCallSendTextMessageAsync_WhenSessionPartnerIdIsNotNullOrEmptyString()
{
var context = new Context { PartnerId = "12345" };
var mockSomeClass = new Mock<ISomeClass>();
// force IsPartner to return true
mockSomeClass.Setup(m => m.IsPartner(context)).Returns(true);
// call PerformAction which should call SendTextMessageAsync
// because IsPartner will return true
await mockSomeClass.Object.PerformAction(context);
// verify SendTextMessageAsync was actually called
mockSomeClass.Verify(m => m.SendTextMessageAsync(It.IsAny<Context>()), Times.AtLeastOnce);
}
}
I keep getting following error:
(Expected invocation on the mock at least once, but was never performed: m => m.SendTextMessageAsync)
which i'm guessing is because SendTextMessageAsync is never called. I'm stuck here though, I don't understand how to properly call it.
I know some (or a lot) of this code doesn't make sense, I've changed it for brevity.
What I'm really just trying to figure out is how can I determine if a function (SendTextMessageAsync) is called when it is wrapped in an if statement that calls another function that returns true.
As rgvlee as already pointed out you can only mock dependencies and verify their method calls.
In your case SomeStaticHelperClass is your dependency and its GetIsPartner method that could be verified.
Unfortunately static classes are not good candidates for mocking. If you could replace that static class reference to an interface then you would be able to mock that easily.
SomeClass uses IPartnerService
public class SomeClass: ISomeClass
{
private readonly IPartnerService partnerSvc;
public SomeClass(IPartnerService partnerSvc)
{
this.partnerSvc = partnerSvc;
}
public async Task<ServiceResponse> PerformAction(Context context)
{
if(IsPartner(context))
{
SendTextMessageAsync(context);
}
}
public bool IsPartner(Context context)
{
return partnerSvc.GetIsPartner(context.PartnerId);
}
public async void SendTextMessageAsync(Context context)
{
// sends the message
}
}
SomeClass is using a IPartnerService mock during unit testing
public class ReceiptServiceTests
{
[Fact]
public async Task GivenAPartner_WhenICallPerformAction_ThenItCallsPartnerService()
{
//Arrange
const string partnerId = "12345";
var context = new Context { PartnerId = partnerId };
var partnerSvcMock = new Mock<IPartnerService>();
partnerSvcMock
.Setup(svc => svc.GetIsPartner(partnerId))
.Returns(true);
var SUT = new SomeClass(partnerSvcMock);
//Act
_ = await SUT.PerformAction(context);
//Assert
partnerSvcMock.Verify(svc => svc.GetIsPartner(partnerId), Times.Once);
}
}
I'm fairly new to this TDD and I'm lost with this at the moment.
I'm trying to use .Setup to get the product by ID of 99 and check it's actually returned in .Returns(saveProduct), which causes me the error below:
enter image description here
What am I doing wrong?
public class ProductControllerTests
{
private Mock<ICart> cartMock;
private Mock<IProductRepository> productRepositoryMock;
private Mock<IOrderRepository> orderRepositoryMock;
private Mock<IProductService> productServiceMock;
private Mock<ILanguageService> languageServiceMock;
private Mock<IStringLocalizer<ProductService>> stringLocalizerMock;
private ProductViewModel product;
private ProductController productController;
public ProductControllerTests()
{
//setup
product = new ProductViewModel();
cartMock = new Mock<ICart>();
productRepositoryMock = new Mock<IProductRepository>();
orderRepositoryMock = new Mock<IOrderRepository>();
stringLocalizerMock = new Mock<IStringLocalizer<ProductService>>();
productServiceMock = new Mock<IProductService>();
languageServiceMock = new Mock<ILanguageService>();
productController = new ProductController(productServiceMock.Object, languageServiceMock.Object);
}
[Fact]
public void CreateValidModelState() // MOCKED
{
// Act
ProductService productService = new ProductService(cartMock.Object, productRepositoryMock.Object, orderRepositoryMock.Object, stringLocalizerMock.Object);
productController = new ProductController(productService, languageServiceMock.Object);
productServiceMock.Setup(x => x.SaveProduct(product)); //It works without this?!? what's it FOR!?
//Arranje
product.Id = 99;
product.Name = "Test box";
product.Description = "The best box ever.";
product.Details = "Toss it and see if it gets back.";
product.Stock = "9000";
product.Price = "9000";
var saveProduct = productController.Create(product);
//productServiceMock.Setup(x => x.GetProductById(It.IsAny<int>())).Returns(saveProduct);
//productServiceMock.SetupGet(x => x.GetProductById(99)).Returns("Test box");
//var expectedProduct = productServiceMock.GetProduct(1);
Assert.IsType<RedirectToActionResult>(saveProduct);
}
}
}
There is a lot of room for improvement in your code snippet.
First, you create private members but then you over write the variable name with local variables.
The idea behind mocking is that when you mock an interface you can Setup its' methods to return whatever you wish them to return. So in your case
productServiceMock.Setup(x => x.GetProductById(99)).Returns(saveProduct);
the line above means that wherever in your controller you have the GetProductById(int) method is called with 99 as a parameter, the method will return the saveProduct object.
You could also write the Setup like
productServiceMock.Setup(x => x.GetProductById(It.IsAny<int>())).Returns(saveProduct);
In this case wherever in your controller the GetProductById() method is called, no matter what is the parameter passed, you will get the saveProductObject.
In this test you have written I can not see any value. What I mean is that create a controller, you create the saveProduct and then you assert it is not null. Of course it is not null, because you populated above.
It would make sense to actually use one of your controllers methods that you know that the GetByUserId() method is used. Then make an assertion upon the return object based on the methods logic.
---Update---
Imagine you have a handler
public class HandlerExample {
private IInjectedService _injectedService;
public HandlerExample(IInjectedService injectedService){
_injectedService = injectedService;
}
public int Handle(testNumber)
{
var serviceResponse = _injectedService.TestMethod(testNumber);
if(serviceResponse)
return 1;
return 2;
}
}
And your interface looks like
public interface IInjectedService
{
bool TestMethod(int testNumber);
}
I won't give any example on the implementation here because it is not relevant. Your test method would then make sense to be like
[Fact]
public void Test()
{
mockedInjectedService = new Mock<IInjectedService>();
mockedInjectedService.Setup(x => x.TestMethod(99)).Returns(true);
var handler = new Handler(mockedInjectedService.Object);
var sut = handler.Handle(99);
Assert.Equal(sut, 1);
}
sut is a convention for "system under test"
I have been tasked with building unit tests for a bunch of legacy code. The specific task/goal for the below method is to test that the messageProcessor.ProcessCustomerPhoneContactInfo(currentPhoneContact) method is being called. I am also posting the test stub I have written so far but I would appreciate some direction because I think I am going down a rabbit hole here. How can I fill in the blanks on my test?
Method being tested:
private void logPhoneCallDialog_SaveContact(Contact currentPhoneContact)
{
if (currentPhoneContact != null)
{
RefreshRenewalActivity();
if (currentPhoneContact.TypeId == ResultType.TookAppointment)
}
NotifyServerOfActivity();
ApplyAppointmentFilters();
this.Activate();
var messageProcessor = new MessageProcessor();
messageProcessor.ProcessCustomerPhoneContactInfo(currentPhoneContact);
}
Test:
[TestFixture, RequiresSTA]
class BucketBrowserTest
{
[Test]
public void logPhoneCallDialog_SaveContact()
{
//Arrange
//Act
//Assert
}
}
Method that calls above method
private void ShowPhoneCallLoggerDialog()
{
PhoneCallLoggerDialog dialog = new PhoneCallLoggerDialog(CurrentCustomer, CurrentBucket.BucketTypeId);
dialog.Owner = this;
dialog.SaveContact += new PhoneCallLoggerDialog.SaveContactHandler(logPhoneCallDialog_SaveContact);
dialog.ShowDialog();
}
Event Handler for calling method
public delegate void SaveContactHandler(PhoneContact currentPhoneContact);
public event SaveContactHandler SaveContact;
Based on the additional information you've supplied, I'm going to outline my assumptions before describing a possible solution:
You're able to safely construct an instance of this class, without calling anything out of process
Calling logPhoneCallDialog_SaveContact(), won't trigger side effects that prevent it from being tested
When refactoring legacy code, you often have to make design choices that you would normally avoid. This can include:
Testing implementation details
Making methods public or internal
Adding light abstractions that simply facilitate testing
In order to get a test around this, you're going to have to do at least one of those things.
Firstly, make logPhoneCallDialog_SaveContact public:
public void logPhoneCallDialog_SaveContact(Contact currentPhoneContact)
{
// same body as before
}
Next, extract a method that holds the entire body of the first one, to end up with this:
public void logPhoneCallDialog_SaveContact(Contact currentPhoneContact)
{
SaveContact(currentPhoneContact);
}
private void SaveContact(Contact currentPhoneContact)
{
if (currentPhoneContact != null)
{
RefreshRenewalActivity();
// This code from your example doesn't compile.
if (currentPhoneContact.TypeId == ResultType.TookAppointment)
}
NotifyServerOfActivity();
ApplyAppointmentFilters();
this.Activate();
var messageProcessor = new MessageProcessor();
messageProcessor.ProcessCustomerPhoneContactInfo(currentPhoneContact);
}
Make the new method public:
public void SaveContact(Contact currentPhoneContact)
{
// same body as before
}
If you haven't already, extract an interface for MessageProcessor:
public interface IMessageProcessor
{
ProcessCustomerPhoneContactInfo(Contact currentPhoneContact);
}
public class MessageProcessor : IMessageProcessor
{
public void ProcessCustomerPhoneContactInfo(Contact currentPhoneContact)
{
// implementation
}
}
Now modify the methods like so:
public void logPhoneCallDialog_SaveContact(Contact currentPhoneContact)
{
var messageProcessor = new MessageProcessor();
SaveContact(currentPhoneContact, messageProcessor);
}
public void SaveContact(
Contact currentPhoneContact,
IMessageProcessor messageProcessor)
{
if (currentPhoneContact != null)
{
RefreshRenewalActivity();
if (currentPhoneContact.TypeId == ResultType.TookAppointment)
}
NotifyServerOfActivity();
ApplyAppointmentFilters();
this.Activate();
messageProcessor.ProcessCustomerPhoneContactInfo(currentPhoneContact);
}
Now write your unit tests against SaveContact, mocking IMessageProcessor, instead of against logPhoneCallDialog_SaveContact.
Edit
Here's an example, as requested. It's been a while since I've used Moq - which was in your original question - so the syntax may not be quite right, but something like this:
[Test]
public void SavesContact()
{
// Arrange
var contact = new Contact();
var messageProcessor = new Mock<IMessageProcessor>();
var subject = // whatever class contains the logPhoneCallDialog_SaveContact method
// Act
subject.SaveContact(contact, messageProcessor.Object);
// Assert
messageProcessor.Verify(x => x.ProcessCustomerPhoneContactInfo(contact), Times.Once());
}
Also test the case where contact is null.
With the code as it stands, you cannot mock out the messageProcessor, but with a few changes, you could:
IMessageProcessorFactory _messageProcessorFactory;
public TheConstructor(IMessageProcessorFactory processorFactory)
{
_messageProcessorFactory = processorFactory;
}
private void logPhoneCallDialog_SaveContact(Contact currentPhoneContact)
{
if (currentPhoneContact != null)
{
RefreshRenewalActivity();
if (currentPhoneContact.TypeId == ResultType.TookAppointment)
}
NotifyServerOfActivity();
ApplyAppointmentFilters();
this.Activate();
var messageProcessor = _messageProcessorFactory.Create();
messageProcessor.ProcessCustomerPhoneContactInfo(currentPhoneContact);
}
Then you can Moq/Mock the interface and find out if the function was called.