Using RhinoMocks, how can I say that one of several methods has been called?

Consider the following service interfaces:

public interface IServiceA { void DoSomething(string s); void DoSomething(string s, bool b); } public interface IServiceB { void DoSomething(); } 

The implementation of IServiceB depends on IServiceA as follows:

 public class ServiceB : IServiceB { private IServiceA _serviceA; public ServiceB(IServiceA serviceA) { _serviceA = serviceA; } public void DoSomething() { _serviceA.DoSomething("Hello", true); } } 

Those. the dependency is inserted into the constructor.

Now consider unit test for the DoSomething() method. I want to argue that one of the overloaded DoSomething methods in IServiceA is called, but as a general principle that unit tests should not know too much about the internal actions of the tested method, I want to be an agnostic regarding which of the two overloads is called. Consider the following unit test:

 [TestFixture] public class ServiceBTests { [Test] public void DoSomething_CallsServiceA() { var serviceAMock = MockRepository.GenerateMock<IServiceA>(); var service = new ServiceB(serviceAMock); service.DoSomething(); // Problem: How to check if EITHER: serviceAMock.AssertWasCalled(s => s.DoSomething(Arg<String>.Is.NotNull, Arg<bool>.Is.Anything)); // OR: serviceAMock.AssertWasCalled(s => s.DoSomething(Arg<String>.Is.NotNull)); } } 

How can I say that either one or the other of these two methods was called?

+2
source share
1 answer

You can manually set the boolean flag as follows:

 [TestFixture] public class ServiceBTests { [Test] public void DoSomething_CallsServiceA() { var serviceAMock = MockRepository.GenerateMock<IServiceA>(); bool called = false; serviceAMock.Stub( x => x.DoSomething(Arg<String>.Is.NotNull, Arg<bool>.Is.Anything)) .WhenCalled(delegate { called = true; }); serviceAMock.Stub(x => x.DoSomething(Arg<String>.Is.NotNull)) .WhenCalled(delegate { called = true; }); var service = new ServiceB(serviceAMock); service.DoSomething(); Assert.IsTrue(called); } } 

I do not think this is very useful. Unit tests concern everything that can be observed beyond the boundaries of the components. The call method for bullying is part of this. In other words, this is normal if you are checking for a specific overload call. In the end, there must be a reason why you are using this overload and not another.

If you really want the unit test to remain implementation-aware, you were not allowed to declare method calls to mocks at all. This will be a serious limitation in your ability to write tests.

+4
source

Source: https://habr.com/ru/post/951739/


All Articles