How to mock method with parameters - moq

I am still learning Moq and am writing a unit test using Moq:
[TestMethod]
public void ProcessFileRowQueue()
{
var mock = new Mock<EdiEntityManager>();
mock.Setup(s => s.GetFileRowEntitiesToProcess()).Returns(GetMockFileRowEntities);
var controller = new EdiController("LOCAL", mock.Object);
controller.ProcessFileRowQueue();
}
This works.
Now, I want to ensure that the ensure ProcessFileRowQueue() actually did it's job. There is a method on EdiManager that I would like to mock so I can intercept the parameters and inspect them and ensure they are correct.
public virtual void SaveNewEdiDocument(EdiDocument ediDocument, Translation translation)...
However, I don't see how to mock a method with parameters.
This is what I thought it would be:
mock.Setup(s => s.SaveNewEdiDocument(It.IsAny<EdiDocument>(), It.IsAny<Translation>()).Returns(ValidateResults));
How do I write this, or is there a different way I should be verifying the results?

I found the Callback method:
[TestMethod]
public void ProcessFileRowQueue()
{
var mock = new Mock<EdiEntityManager>();
mock.Setup(s => s.GetFileRowEntitiesToProcess()).Returns(GetMockFileRowEntities);
mock.Setup(s => s.SaveNewEdiDocument(It.IsAny<EdiDocument>(), It.IsAny<Translation>()))
.Callback<EdiDocument, Translation>(VerifyResult);
var controller = new EdiController("LOCAL", mock.Object);
controller.ProcessFileRowQueue();
}
public void VerifyResult(EdiDocument ediDocument, Translation translation)
{
}

Related

How to convert to Xunit using mocking

I have these two methods in my service class
public class PatientService : IPatientService
{
private readonly IRestClient _restClient;
private readonly IAppSettings _appSettings;
public PatientService(IRestClient restClient, IAppSettings appSettings)
{
_restClient = restClient;
_appSettings = appSettings;
}
public async Task<IList<PatientViewModel>> GetPatients(int wardId)
{
var url = _appSettings.Server + _appSettings.PatientServiceEndPoint + wardId;
var token = _appSettings.Token;
return GetPatientList(await _restClient.GetAsync<List<PatientInfo>>(url, token));
}
public IList<PatientViewModel> GetPatientList(IList<PatientInfo> patientInfoList)
{
return patientInfoList.Select(p => new PatientViewModel(p)).ToList();
}
}
I need to add this code to my Xunit.cs. How to do it?
I've implemented this and I do not know how to proceed.
private readonly PatientListPageViewModel _patientListPageViewModel;
private readonly Mock<IPatientService> _patient;
public PatientServiceTests()
{
_patient = new Mock<IPatientService>();
_patientListPageViewModel = new PatientListPageViewModel(_patient.Object);
}
[Fact]
public void GetListByWard_PassingWardId_GetPatientsCountAccordingToWardId()
{
}
This is what I tried to do. How to convert those two methods in service to be testable?
You did get mocking a bit wrong. It is not the component under test that is mocked, but its dependencies. When unit-testing you'd like to test a unit in isolation. Your case of mocking would be kind of correct if you unit-tested the PatientListPageViewModel, but since your test class is named PatientServiceTests I assume that you really wanted to test PatientService. If you wanted to test the former, you would be quite right to mock IPatientService, but when testing PatientService, IRestClient and IAppSettings shall be mocked
public PatientServiceTests()
{
_restClientMock = new Mock<IRestClient>();
_appSettingsMock = new Mock<IAppSettings>();
_patientService = new PatientService(_restClientMock.Object, _appSettingsMock.Object);
}
And your test could be something like
[Fact]
public async Task ReturnsCorrectPatientList() // async supported as of xUnit 1.9
{
// set up the mock
_restClientMock.SetUp(restClient => restClient.GetAsync<List<Patient>>(It.IsAny<string>(), It.IsAny<string>())
.Returns(() => Task.FromResult(/* what patients it shall return */));
var result = await _patientService.GetPatients(0);
// compare whether the returned result matches your expectations
}
If you wanted to test whether the URL is formed correctly, you could use Verify
[Theory]
[InlineData("SERVER", "ENDPOINT", 12, "1234", "SERVERENDPOINT12")]
[InlineData("https://localhost:65000", "/patients/", 5, https://localhost:65000/patients/5")]
public void TestWhetherCorrectUrlIsCalled(string server, string endpoint, int wardId, string token, string expectedUrl)
{
_appSettingsMock.SetupGet(appSettings => appSettings.Server).Returns(server);
_appSettingsMock.SetupGet(appSettings => appSettings.PatientServiceEndPoint).Returns(endpoint);
_appSettingsMock.SetupGet(appSettings => appSettings.Token).Returns(token);
_restClientMock.SetUp(restClient => restClient.GetAsync<List<Patient>>(It.IsAny<string>(), It.IsAny<string>())
.Returns(() => Task.FromResult(new List<Patient>()));
// we do not need the result
await _patientService.GetPatients(wardId);
_restClientMock.Verify(restClient => restClient.GetAsync<List<Patient>>(exptectedUrl, token), Times.Once);
}
We are setting up the IRestClient in this case, since it would return null otherwise. And await null would cause your test to fail. After GetPatients has been called we are using Verify to verify that GetAsync has been called with the correct parameters. If it has not been called, Verify will throw and your test will fail. Times.Once means, that GetAsync shall have been called once and only once.
On a side note: Viewmodels shall have a meaning in the context of your user interface only. Services shall be independent and hence not return viewmodels, as you did, but POCOs (or maybe domain models). In this case the interface of your service should be
public interface IPatientService
{
public async Task<IList<Patient>> GetPatients(int wardId);
// ...
}

How to test the method passed to subscribe method of the PubSubEvent in the Wpf Prism library?

I have two ViewModels, MainWindowShellViewModel(shellVm) and MainWindowContentViewModel(contentVm). The shellVm publishes an event and the contentVm subscribes to it.
The shell VM looks something like the following. I have omitted many details.
// ctor
public MainWindowShellViewModel(IEventAggregator eventAggregator)
{
_EventAggregator = eventAggregator ?? throw new ArgumentNullException(nameof(IEventAggregator) + " service injected is null!!!");
_AppStartingClosingEventToken = _EventAggregator.GetEvent<AppStartingClosingEvent>();
}
private void MainWindowShellLoaded()
{
var payload = new AppStartingClosingEventData();
payload.Data = "MainWindowStarting";
_AppStartingClosingEventToken.Publish(payload);
}
The AppStartingClosingEvent is a no brainer type as follows.
public class AppStartingClosingEvent : PubSubEvent<AppStartingClosingEventData>
{ }
public class AppStartingClosingEventData
{
public string Data { get; set; }
}
And finally, the contentVm looks as follows.
public MainWindowContentViewModel(IEventAggregator eventAggregator)
{
_AppClosingEventToken.Subscribe(AppStartingClosing);
}
private void AppStartingClosing(AppStartingClosingEventData appStartingClosingEventData)
{
if (appStartingClosingEventData.Data == "MainWindowStarting")
LoadState(appStartingClosingEventData);
if (appStartingClosingEventData.Data == "MainWindowClosing")
SaveState(appStartingClosingEventData);
}
I want to test the that the method AppStartingClosing inside of contentVm is called with proper data. I am using Moq
I am running out of ideas. Please suggest. Tried the following but so far no success.
How do I test Prism event aggregator subscriptions, on the UIThread?
Using Moq to verify a Prism event subscription fails
Unit testing with Moq, Prism 6, and Event Aggregation
Moq Event Aggregator Is it possible
// Verifying a delegate was called with Moq
EDIT
Here is what I have tried.
// Arrange
var mockingKernel = new MoqMockingKernel();
var eventAggregatorMock = mockingKernel.GetMock<IEventAggregator>();
var eventBeingListenedTo = new AppStartingClosingEvent();
eventAggregatorMock.Setup(e => e.GetEvent<AppStartingClosingEvent>()).Returns(eventBeingListenedTo);
var vm = mockingKernel.Get<MainWindowContentViewModel>();
var evData = new AppStartingClosingEventData();
evData.Data = "MainWindowStarting";
// Act
eventBeingListenedTo.Publish(evData);
Now, what should I do? I am not even clear if I have approached correctly.
Now what should I do?
After eventBeingListenedTo.Publish(evData); look whether whatever effect SaveState should have is actually happening.
I am not even clear if I have approached correctly.
You do not want to test whether one method in a class is called by another method of that class.
So instead of trying to do
subjectUnderTest.DoStuff();
MagicallyVerifyThatThisGotCalled( () => subjectUnderTest.SomeEffect() );
you should do
var subjectUnderTest = new SubjectUnderTest( serviceMock.Object );
subjectUnderTest.DoStuff();
serviceMock.Verify( x => x.SomeEffectOnTheService(), Times.Once );
Assert.That( subjectUnderTest.SomePropertyThatsChanged, Is.EqualTo( newValue ) );
Whatever SubjectUnderTest does internally to achieve the desired effect, is not in the scope of the test. It's private to SubjectUnderTest, you don't care how it is done as long as it is done at all. When testing, look at the externally visible state of your subject under test, and what it does to its dependencies.

How to setup Moq to execute some methods of a Moq

I have a test where I pass in an object like so:
var repo = new ActualRepo();
var sut = new Sut(repo);
In my test, Repo has one method that I need to actually execute, whilst another method I want to mock out and not execute.
So for example, take this pseudocode:
var repo = new Mock<IRepo>();
repo.Setup(m => m.MethodIWantToCall()).WillBeExecuted();
repo.Setup(m => m.MethodIWantToMock()).Returns(false);
Using Moq, is this possible and how can it be done?
EDIT:
I've used TypeMock in the past and you can do something like.
Isolator.When(() => repo.MethodToIgnore()).WillBeIgnored();
Isolator.When(() => repo.MethodToActuallyRun()).WillBeExecuted();
Not too sure from the question if this is useful but it is possible to partially mock an object if the method that you want to mock is virtual.
public class Foo {
public string GetLive() {
return "Hello";
}
public virtual string GetMock() {
return "Hello";
}
}
public class Snafu {
private Foo _foo;
public Snafu(Foo foo) {
_foo = foo;
}
public string GetMessage() {
return string.Format("{0} {1}", _foo.GetLive(), _foo.GetMock());
}
}
[TestMethod]
public void NotMocked() {
var snafu = new Snafu(new Foo());
Assert.AreEqual("Hello Hello", snafu.GetMessage());
}
[TestMethod]
public void Mocked() {
var mockFoo = new Mock<Foo>();
mockFoo.Setup(mk => mk.GetMock()).Returns("World");
var snafu = new Snafu(mockFoo.Object);
Assert.AreEqual("Hello World", snafu.GetMessage());
}
You can't do this with Moq if you use the same object unless one of the method is virtual and you are basing your mock on a type rather than an interface.
That's because when you are passing a mock object based on an interface, you aren't passing a real object so it does not have access to the real methods of the object.
You are passing a dynamic proxy which will respond to methods it has been setup to respond to.
I believe TypeMock rewrites the assemblies at runtime to achieve this, something Moq definitively doesn't do.
If you want to achieve similar results with Moq:
You could mock both methods
You would have to extract both methods to different dependencies so as to mock one dependency and not the other.
You could have the method you need mocked be virtual, which would be the solution I would prefer.
EDIT : I edited my answer for correctness after reading AlanT's answer.

Moq: setting up for a method which returns no value

I'm trying to mock out a call to a repository. I can successfully do so when a repository call returns a value by using Setup().Returns:
mock.Setup(m => m.Get(param)).Returns(new CustomObject());
However, when I try to do the same sort of Setup for repository calls which return no values, Moq throws an exception and tells me this method was never called i.e.Expected invocation on the mock exactly 1 times, but was 0 times
Precisely, I'm doing this:
mock.Setup(m => m.UpdateRepository(param1)); // UpdateRepository returns no value
service.DoUpdate(param1);
mock.Verify(m => m.UpdateRepository(param1), Times.Exactly(1));
Note: DoUpdate method only calls repository.UpdateRepository(param1);
Am I not using Moq setup correctly in this instance? Is there a different way to Setup methods which return no value?
Thanks in advance!
You don't need to setup the call to UpdateRepository. Just verify it.
Given these types:
public interface IRepository
{
void UpdateRepository(string value);
}
public class Service
{
public Service(IRepository repository)
{
_repository = repository;
}
public void DoUpdate(string value)
{
_repository.UpdateRepository(value);
}
private IRepository _repository;
}
Your test method could be as follows:
const string param1 = "whatever";
var repoMock = new Mock<IRepository>();
var sut = new Service(repoMock.Object);
sut.DoUpdate(param1);
repoMock.Verify(x => x.UpdateRepository(param1), Times.Once());
Try using Verifiable:
mock.Setup(m => m.UpdateRepository(param1)).Verifiable();

How to Verify another method in the class was called using Moq

This seems like something simple but I can't seem to get it to work.
I have a class with a Save method that simply calls another method ShouldBeCalled(). I want to verify that if I call Save() that the other method ShouldBeCalled() is executed at least once. I thought that I could do the following.
public class ClassA
{
public virtual void Save()
{
ShouldBeCalled();
}
public virtual void ShouldBeCalled()
{
//This should get executed
}
}
[TestFixture]
public class ClassA_Test
{
[Test]
public void Save_Should_Call_ShouldBeCalled()
{
var mockClassA = new Mock<ClassA>();
mockClassA.Object.Save();
mockClassA.Verify(x => x.ShouldBeCalled(), Times.AtLeastOnce());
}
}
But I get the exception "Expected invocation on the mock at least once, but was never performed: x => x.ShouldBeCalled()"
It is just a guess but Is Moq overriding the Save() method with it's own version which ignores anything I have inside the real object's Save() method.
You are having this problem because you are mocking what you are testing. This doesn't make sense.
You are correct that Moq will replace the implementation of your method with its own. The reason is you are supposed to use Moq to mock things the class you are testing calls, not the class you are testing itself.
This test would be appropriate if your code were designed thusly:
public class ClassA
{
BusinessLogicClass bl;
public ClassA(BusinessLogicClass bl)
{
this.bl = bl;
}
public void Save()
{
bl.ShouldBeCalled();
}
}
public class BusinessLogicClass
{
public virtual void ShouldBeCalled()
{
//This should get executed
}
}
And here is the correct test of that method now:
[TestFixture]
public class ClassA_Test
{
[Test]
public void Save_ShouldCallShouldBeCalled()
{
//Arrange
var mockBLClass = new Mock<BusinessLogicClass>();
mockBLClass.Setup(x => x.ShouldBeCalled()).Verifyable();
//Act
ClassA classA = new ClassA(mockBLClass.Object);
classA.Save();
//Assert
mockBLClass.VerifyAll();
}
}
The key lesson here is that you mock/stub what your test needs to run, not what you are testing itself.
Hope this helps,
Anderson
Try using the CallBase = true and then false. I ran your code and it works.
var mockClassA = new Mock<ClassA>();
mockClassA.CallBase = true;
mockClassA.Object.Save();
mockClassA.CallBase = false;
mockClassA.Verify(x => x.ShouldBeCalled(), Times.AtLeastOnce());
Yes, this can be done. However, you need to add a line of code to have Moq track whether or not the ShouldBeCalled method was indeed called.
Something like the following will work:
var mockClassA = new Mock<ClassA>();
mockClassA.Setup(x => x.ShouldBeCalled()).Verifiable();
mockClassA.Object.Save();
mockClassA.Verify(x => s.ShouldBeCalled(), Times.AtLeastOnce());
The Setup method sets up expectations. When you call Verify, you are asking Moq to verify these expectations. If you don't make a Setup call to create expectations for the ShouldBeCalled method, then Moq doesn't consider it to be trackable and will therefore fail hard when you try to Verify it.
You can stub methods in the system under test using CallBase.
[TestFixture]
public class ClassA_Test
{
[Test]
public void Save_Should_Call_ShouldBeCalled()
{
// Arrange
var mockClassA = new Mock<ClassA>();
mockClassA.CallBase = true; // this will call real methods unless the method is mocked/stubbed.
mockClassA.Setup(a => a.ShouldBeCalled());
// Act
mockClassA.Save();
// Assert
mockClassA.Verify(a => a.ShouldBeCalled(), Times.Once());
}
}

Resources