Mocks to verify interaction - c#

Typically when I need to mock out a class for testing, I'll use a library such as Rhino Mocks. Here I have a class called MyService that expects a IEmailSender.
public class MyService
{
private readonly IEmailSender sender;
public MyService(IEmailSender sender)
{
this.sender = sender;
}
public void Start()
{
this.sender.SendEmail();
}
}
If I needed to test the interaction between these two objects, my test would look something like this:
[TestMethod]
public void Start_Test_Using_Rhino_Mocks()
{
IEmailSender emailSender = MockRepository.GenerateMock<IEmailSender>();
MyService service = new MyService(emailSender);
service.Start();
emailSender.AssertWasCalled
(
x => x.SendEmail(),
c => c.Repeat.Once()
);
}
In the test above, I'm using Rhino Mocks to generate the mock and assert that the SendEmail() method was called once.
But what if I could not use Rhino Mocks and had to create manual mocks?
public class MockEmailSender : IEmailSender
{
public void SendEmail()
{
}
}
[TestMethod]
public void Start_Test_Using_Manual_Mocks()
{
MockEmailSender emailSender = new MockEmailSender();
MyService service = new MyService(emailSender);
service.Start();
// How do I test the interaction?
}
With the mock that I created manually, how would I verify that the SendEmail() method was called? I could put my assertions in the SendEmail() method of the mock, but that would make the test hard to understand since I don't immediately see what's going on when I look at the test.

A very simple solution would have your manual mock just be a stateholder, with counters for the calls to each method. But it's fragile ...
public class MockEmailSender : IEmailSender
{
public int SendCount = 0;
public void SendMail(...)
{
SendCount++;
}
// ... other IEmailSender methods ...
}
Then just query SendCount after making your method call, and making sure that it's == 1.
Remember, Rhino Mocks is creating this dynamically for you -- if you do it manually you have to react to interface changes before compile time, by hand.

I think that you have no other option than setting a flag in "SendEmail()", and checking that flag from the test throgh a new method of MockEmailSender like "sendMailWasInvoked()" or something like this (which is in fact a kind of "verify").
You can extend this to count the number of invokations, parameters...

well i would advise against creating any manual Mocks (because if you add new method to interface, it gets broken).
if you really have to do it, when expose some counter/bool in your MockEmailSender and you can Assert it later on.
Assert.IsTrue(emailSender.IsCalled)

Related

Unit testing Reactive code in constructors using AutoMock from AutoFixture?

I'm hitting a bit of a chicken and egg problem setting up my mocks for Reactive Extensions code in a constructor. Here's the class under test (along with the service interface it depends on):
class MyViewModel
{
public int Thing { get; set; }
public MyViewModel(IMyService service)
{
service.StreamOfThings.Subscribe(x => Thing = x));
}
public void SomeClickEvent()
{
// Do something with `Thing`
}
}
public interface IMyService
{
IObservable<int> StreamOfThings { get; }
}
To make testing easier, I have also defined a custom attribute named AutoMockData I can use to use Moq to inject mock instances into my classes through AutoFixture:
public class AutoMockDataAttribute : AutoDataAttribute
{
private static IFixture Create() =>
new Fixture().Customize(new AutoMoqCustomization { ConfigureMembers = true });
public AutoMockDataAttribute() : base(Create) {}
}
With this, I am ready to write my test (using NUnit3):
[Test, AutoMockData]
public void Verify_some_behavior(
[Frozen] Mock<IMyService> mockService,
MyViewModel vm)
{
mockService.Setup(x => x.StreamOfThings).Returns(Observable.Return(100));
vm.SomeClickEvent();
vm.Thing.Should().Be(100);
}
This test fails. I believe this fails because the constructor of MyViewModel sets up an observable pipeline on a different instance of IObservable than the one I set up in the unit test method.
The ideal solution here would be to use the IObservable<> instance that was set up using AutoFixture, but I'm not sure how to best do that. It would somehow need to already set up a pre-constructed pipeline for me.
The workaround I have found is to not use the AutoMock functionality of AutoFixture and instead construct a Fixture directly and directly use the .Freeze() and .Create() methods in the proper order. However, this leads to an arguably more difficult to read and less clean unit test body.
How can I continue to implement my test as shown here but also be able to set up any observables before they are used in the SUT's constructor?
I think the issue here is that you never actually exercise the observable, so Thing keeps the value that AutoFixture assigned it on creation.
In the example below the Subject is frozen as an IObservable<int> which is then resolved as the return value for the StreamOfThings. Then the subject is forced to trigger the subscribers.
[Test, AutoMockData]
public void Verify_some_behavior(
[Frozen(Matching.ImplementedInterfaces)] Subject<int> observable,
MyViewModel vm)
{
observable.OnNext(100);
vm.SomeClickEvent();
vm.Thing.Should().Be(100);
}
The example is equivalent to the following:
[Test, AutoMockData]
public void Verify_some_behavior(
Subject<int> observable,
[Frozen] Mock<IMyService> mockService,
MyViewModel vm)
{
mockService.Setup(x => x.StreamOfThings).Returns(observable);
observable.OnNext(100);
vm.SomeClickEvent();
vm.Thing.Should().Be(100);
}
This way of writing the test should also make it obvious how to handle multiple observable properties.

How do I setup MOQ to Set property Objects and verify the method [duplicate]

It is my understanding that I can test that a method call will occur if I call a higher level method, i.e.:
public abstract class SomeClass()
{
public void SomeMehod()
{
SomeOtherMethod();
}
internal abstract void SomeOtherMethod();
}
I want to test that if I call SomeMethod() then I expect that SomeOtherMethod() will be called.
Am I right in thinking this sort of test is available in a mocking framework?
You can see if a method in something you have mocked has been called by using Verify, e.g.:
static void Main(string[] args)
{
Mock<ITest> mock = new Mock<ITest>();
ClassBeingTested testedClass = new ClassBeingTested();
testedClass.WorkMethod(mock.Object);
mock.Verify(m => m.MethodToCheckIfCalled());
}
class ClassBeingTested
{
public void WorkMethod(ITest test)
{
//test.MethodToCheckIfCalled();
}
}
public interface ITest
{
void MethodToCheckIfCalled();
}
If the line is left commented it will throw a MockException when you call Verify. If it is uncommented it will pass.
No, mock testing assumes you are using certain testable design patterns, one of which is injection. In your case you would be testing SomeClass.SomeMethod and SomeOtherMethod must be implemented in another entity which needs to be interfaced.
Your Someclass constructor would look like New(ISomeOtherClass). Then you would mock the ISomeOtherClass and set expectation on its SomeOtherMethod to be called and verify the expectation.
Even though I agree that the #Paul's answer is the recommended way to go I just want to add one alternative way which is provided by moq off the self.
Since SomeClass is abstract it is indeed mockable, but public void SomeMehod() isn't. The point is to find the way to mock and somehow invoke that method and then using CallBase propagate the call to the SomeOtherMethod(). It might sound as a hack but it is simple in essence. It could be used in the case if the proposed refactoring is not possible.
// This class is used only for test and purpose is make SomeMethod mockable
public abstract class DummyClass : SomeClass
{
public virtual void DummyMethod() => base.SomeMethod();
}
Then you could setup DummyMethod() to propagate the call by setting CallBase flag.
//Arrange
var mock = new Mock<DummyClass>();
mock.Setup(m => m.DummyMethod()).CallBase();
//Act
mock.Object.SomeMethod();
//Assert
mock.Verify(m => m.SomeOtherMethod(), Times.Once);

How to unit test delegate was received in base class method?

I currently have a base service class that all my services extend. This is what one of the methods look like:
protected internal virtual T PerformServiceOperationWithExceptionHandling<T>(Func<T> func)
{
try
{
return func.Invoke();
}
...
}
In the derived classes I call the method like this:
public AddGuestResponse AddGuest(AddGuestRequest addGuestRequest)
{
return PerformServiceOperationWithExceptionHandling(() => AddGuestLogic(addGuestRequest));
}
I want to test AddGuest and ensure "AddGuestLogic" is being passed as a parameter in the base method? How do I achieve this with nSubstitute and nUnit. I don't think its possible?
================================================
I ended up using the following code:
[Test]
public void AddGuest_WhenCalled_PerformsAddGuestLogicWithExceptionHandling()
{
Func<AddGuestResponse> addGuestLogic = null;
_guestService.PerformServiceOperationWithExceptionHandling(Arg.Do<Func<AddGuestResponse>>(arg => addGuestLogic = arg));
var addGuestRequest = new AddGuestRequest();
_guestService.AddGuest(addGuestRequest);
_guestService.ClearReceivedCalls();
addGuestLogic.Invoke();
_guestService.Received().AddGuestLogic(addGuestRequest);
}
The _guestService is created in my setup method as follows: Substitute.ForPartsOf();
I second Sunny Milenov's answer, but would go one step further by advising you to change your design. I have learned the hard way that many of these headaches with testing base class behavior go away when you follow the principle of composition over inheritance.
I.e., if you refactor your base class to a collaborator, which you inject into your services' constructor, you can test that in isolation and mock it in your services' tests. No worrying about testing an abstract base class or testing the same exception handling in all of your services' tests.
You would test that the collaborator correctly invokes the func in the collaborator's tests.
In the services' tests you can just mock the collaborator to return the Func's result right away:
[Test]
public void ServiceLogicIsExecuted()
{
var collaborator = Substitute.For<ICollaborator>();
//Tell the test double to return the Func's result. You'd probably want to do this in the setup method.
collaborator.PerformServiceOperation(Arg.Any<Func<int>>()).Returns(x => ((Func<int>)x[0]).Invoke());
var sut = new Service(collaborator);
var result = sut.CalculateSomething();
Assert.That(result, Is.EqualTo(99));
}
public class Service
{
private readonly ICollaborator _collaborator;
public Service(ICollaborator collaborator)
{
_collaborator = collaborator;
}
public int CalculateSomething()
{
return _collaborator.PerformServiceOperation(ExecuteLogic);
}
private static int ExecuteLogic()
{
return 99;
}
}
public interface ICollaborator
{
T PerformServiceOperation<T>(Func<T> func);
}
Short answer - you shouldn't. Unit testing is about testing the behavior of the tested method, not the implementation details.
Long answer:
It doesn't matter how the class internally works, as far as it produces the expected results.
You need to test your public method on the final class and see if this works as expected. Testing a base/abstract class in isolation proves nothing.

Are my NUnit tests actually running correctly?

I'm trying to be a good developer and actually right some unit tests for some code I have written.
I am using NUnit with Ninject.MockingKernel.Moq and followed the documentation on https://github.com/ninject/ninject.mockingkernel/wiki/Examples. Here is an example of what I have been working with
[TestFixture]
public class MyUnitTest
{
private readonly MoqMockingKernel _kernel;
public MyUnitTest()
{
_kernel = new MoqMockingKernel();
}
[SetUp]
public void SetUp()
{
_kernel.Reset(); // Not really sure why this is included (something to do with caching...)
}
[Test]
public void MyTest()
{
var moqService = _kernel.GetMock<IMyService>();
moqService.Setup(x=>x.MyMethod("With parameter")
.Returns(new MyObject {Id = 1, Name = "With parameter"});
var service = _kernel.Get<IMyService>();
service.MyMethod("With parameter");
moqService.VerifyAll();
}
}
Now, to my amazement this actually works but is it actually testing the logic in the code? Or is it saying when you return this method this is what will be returned?
I did a small test, MyMethod returns an object:
var method = service.MyMothod("With parameter");
Debugged the test and method.Id does in fact equal 1 so I'm 75% certain it's working but I thought it best to check with someone more knowledgeable than myself!
If your goal is to test a IMyService that you implemented elsewhere, you are doing it wrong. What you are doing is creating a mock IMyService and testing that it is correctly mocked, which achieves not much.
You should use kernel.GetMock() if you need an IFoo to test your IMyService because your implementation of IMyService takes a IFoo as a parameter of its constructor (like it is done in the example that you linked).

Where to instantiate interface in Nunit test

I think theres something really simple I'm missing so I apologize in advance. I'm trying to test an interface with Nunit. The interface is implemented by a class derived from a base class and I'm using Castle Windsor for IOC. I simply dont know where to assign the interface in the derived test class.
Here is the base test class
[TestFixture]
public class BaseTest
{
protected ISession session;
[SetUp]
public void setup() {
NHibernateConfig.Init(
MsSqlConfiguration.MsSql2008.ConnectionString(
builder =>
builder.Server("localhost")
.Database("Db_test")
.TrustedConnection()),
RebuildDatabase());
session = NHibernateConfig.CreateAndOpenSession();
}
[Test]
public void Shoud_Test_Connection(){
// testing connection via setup fixture
}
[TearDown]
public void TearDown(){
if (session != null)
session.Dispose();
}
private Action<Configuration> RebuildDatabase() {
return config => new SchemaExport(config).Create(false, true);
}
}
here is the derived test class
[TestFixture]
public class RepositoryTest : BaseTest
{
IRepository repository;
[SetUp]
public void Setup(){
// I think the interface should get assigned
// in here somehow....
}
[Test]
public void Should_Create_And_Read(){
var post = CreatePost();
var actual = (IList) repository.GetAll();
Assert.Contains(post, actual);
Assert.AreEqual(1, actual.Count);
}
}
I have the repository registered in my windsor container and works fine in all my controllers, just cant figure out how to test the interface. My only solution is to assign the interface a concrete implementation in the setup method but I'm wondering if I'm suppose to use DI to handle that somehow.
Ask and you shall receive :)
You need a reference to your container in your test and you need to call .Resolve() I believe that is what Castle calls their method but I could be wrong.
In order to get a reference to your container in your test you need to create your container at some point. I am not really a Castle expert but check out the code on this page looks like a pretty simple example on how to new up a container and resolve a dependency
http://stw.castleproject.org/Windsor.MainPage.ashx

Categories

Resources