I have a method called GetBESummaries which looks like this:
public string GetBESummaries()
{
CheckPermissions();
/* rest of the code */
}
public void CheckPermissions()
{
method1();
method2();
}
I am writing a unit test method using moq and i want my moq to ignore CheckPermissions so that i can avoid mocking the list of method calls from Check Permissions. I wish to prevent the control frm going inside the CheckPermissions method. What is the best way to achieve this?
At a high level, Moq works by overriding implementation for abstract and virtualized members. You would need to break out your permissions logic into either an abstract class or an interface so that it could be overridden. While you're at it, consider giving it a return type so that you can do something with your permissions validation logic outside of the permissions class. Your main class can then require the permissions object in its constructor. For example,
public interface IPermissionsChecker
{
bool UserHasPermissions( // whatever parameters you need );
}
public class PermissionsChecker : IPermissionsChecker
{
public override bool UserHasPermissions( // same params as above)
{
// logic
}
}
Once you're there, mocking it out is very easy. You just build the mock, write the setup logic for how you want it to behave inside of your tests, and feed it into your consuming class. This has the added bonus of improving your encapsulation: if you want to have different methods of confirming permissions, it's simply a matter of submitting a different one to your constructor or calling method!
var myMock = new Mock<IPermissions>();
myMock.Setup( m => m.UseHasPermissions()).Returns(true);
var classUnderTest = new GenericConsumerClass(myMock);
Related
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);
I am new to the whole MOQ movement... which by the way is pretty cool ... and I am mocking all kinds of stuff now..
Anyway, I ran into this scenario and was wondering how to go about mocking it up.
I have an class that implements the interface that I want to mock:
public interface ImyInterface
{
void doit();
}
public abstract class myBase<TChannel> : ICommunicationObject, IDisposable where TChannel : class
{
protected TChannel Channel { get; private set; }
// ICommunicationObject implementation not shown
}
public class myIIntClass : myBase<ImyInterface>, ImyInterface
{
public myIIntClass()
{
}
public void doit()
{
Channel.doit();
}
}
I think my moq test doesn't mock anything... but I am unsure and hoping to get some insight on how to either write it correctly or refactor my class:
Here is my current MOQ test:
MyClass myClass = null;
Mock<ImyInterface> moq = new Mock<ImyInterface>();
moq.Setup(x => x.doit());
myClass = (MyClass)moq.Object;
myClass.doit();
moq.VerifyAll();
Thanks from one moqer to another... :-)
I feel like maybe you're missing the point of mocking here. You mock dependencies that exist in a unit of work you're testing. So, let's say I'm testing doit here in the concrete implementation of MyClass; I want to make sure it works right. Now, let's say that method has a dependency to another class; it calls a method on it that returns a boolean value. What I want to do is mock that class because I want to make sure that MyClass.doit behaves right when it returns true and when it returns false.
See, in the example above, what I've done is ensured that no other dependencies are affecting the code flow of MyClass.doit; I'm forcing MyClass.doit down a very specific path; I want to test that path.
The code you've created literally performs nothing because it just executes the mocked up method.
You don't mock/stub the unit under test. If you are testing the doIt(), you don't mock that, you mock its (or class) dependencies.
Is it possible to do some form of expect NEW in rhino mock.
Example:
public void ToBeTested()
{
ClassForExmaple classForExample = new ClassForExample();
//Other logic.....
}
So I want my unit test to call ToBeTested(), but when the new ClassForExample is called I want it to return a mocked version.
I have not worked with Rhino mock and I am not sure if this is something that is supported by RhinoMock but the fact that the control of creation of the object is embedded within the method violates the principles of DI/IOC and thus is harder to test.. Ideally the class should have been injected to the method either through the constructor of the containing class or to the method itself..
thus
class A
{
IClassForExample _classForExample;
public A(IClassForExample classForExample)
{
_classForExample=classForExample;
}
public void ToBeTested()
{
var classForExample = _classForExample;
//Other logic.....
}
}
Does RhinoSupport extending a non-abstract/interface class - a question I am not sure but I am sure it can mock the interface.
No, it's not possible, for the same reason you cannot expect static things : it is not called on an instance.
If you want to use a mock for an object that is built within your tested code, you should have something like this :
internal virtual ClassForExample NewClassForExempe()
{
return new ClassForExample();
}
and then mock this method in your test.
Note : I put the method internal assuming you have rhino mocks declared in InternalsVisibleToAttribute of your class. Otherwise you'll have to make it public.
Note: This question has been updated with new info. Please see the bottom half of this text. (The original quesiton is left here for context.)
Is there any way I can define my attribute so that if it's defined on a method that is overidden, the attribute is still applied?
The reason I ask is that I have an attribute which injects some behavior into the method, but the behavior is not applied when the method is called as in any of the cases in the child class, and I would like it to be.
class BaseClass
{
[MyThing]
virtual void SomeMethod()
{
// Do something fancy because of the attribute.
}
}
class ChildClass
{
override void SomeMethod()
{
// Fancy stuff does happen here too...
base.SomeMethod();
}
void AnotherMethod()
{
// ...but not here. And I'd like it to =(
base.SomeMethod();
}
}
The attribute is defined like so:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class MyThingAttribute : Attribute
The current code for finding methods with the attribute is the following:
var implementation = typeof(TheTypeWereCurrentlyInvestigating);
var allMethods = (from m in implementation.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy)
let attribs = (TransactionAttribute[]) m.GetCustomAttributes(typeof (TransactionAttribute), true)
where attribs.Length > 0
select Tuple.Create(m, attribs.Length > 0 ? attribs[0] : null)).ToList();
I didn't write that part, and I can't say I am 100% of what every part of it does... But we can assume, for now, that I am in control of all the involved code. (It's an opensource project, so I can at least create my own version, and submit a patch to the project owners...)
I have a couple of other cases too - basically I want to have this behavior injected whenever I call the method on the base class, no matter which way I got there - but if I solve this one I might get ideas on how to get the others working. If not, I'll get back with them.
UPDATE:
OK, so I sat down with the Castle.Transactions project and created some very simple tests to see what works and what doesn't. It turns out that my original assumptions on what works and what doesn't were somewhat off.
What I did:
I created a test class which has one method, decorated with the attribute, and which calls an Assert method that verifies that the behavior was injected correctly (i.e. that there is a transaction). I then created a couple of classes which inherit this test class, to see in which cases everything works as I expect it to.
What I found:
By calling the test method directly on the test class and from various methods on the child classes, I discovered the following about what works and what doesn't:
Method called Access modifiers Does it work?
************* **************** *************
SomeMethod() on base class* N/A Yes
OtherMethod() on child neither NO <-- headache!
OtherMethod() on child hiding (new) No
SomeMethod() on child hiding (new) No
OtherMethod() on child overrides No
OtherMethod() on child* overrides Yes
SomeMethod() on child overrides Yes
In all cases except the one marked with *, base.SomeMethod() was called from the method applied in the test. In the first case the same method was called but directly from the test, since no child class is involved. In the second case (of the ones marked *), the overriding method was called, i.e. this.SomeMethod(), so that's really equivalent of the last case. I'm not using any redundant qualifiers, so in that method the call is simply SomeMethod().
What I want:
It's the case marked "headache" that I really want to solve; how to inject behavior into the base class even though I'm calling it from my child class.
The reason I need that specific case to work is that I'm using this pattern in a repository, where the base class defines a Save(T entity) method decorated with the Transaction attribute. Currently, I have to override this method just to get the transaction orchestration, which makes it impossible to change the return type; on the base class it's void, but on my implementation I'd like to make it Error<T> instead. This is impossible when overriding, and since I can't solve the problem by naming the method differently, I'm at a loss.
If I were you I'd try and change your design. Calling base.SomeMethod() in AnotherMethod() when it has been overridden in AnotherMethod's class really smells.
Can't you factor out in a protected method the relevant part of BaseClass.SomeMethod(), place your attribute on this new method and call it in BaseClass.SomeMethod() and AnotherMethod(), assuming ChildClass.SomeMethod() would still call the method it overrides?
Can't go over it. Can't go under it. Gotta go around it.
Considering your circumstances as I understand them:
Can't apply the existing attribute to inject commit/rollback: It would never roll back because you're catching exceptions yourself in AnotherMethod().
You need the commit/rollback injection in AnotherMethod().
I suspect that TransactionAttribute is wrapping the method's body in a try-catch block, transforming this (pseudocode):
public void SomeMethod() {
DoStuff();
}
Into something like this (pseudocode, and very simplified):
public void SomeMethod() {
transaction.Begin();
try {
DoStuff();
transaction.Commit();
}
catch {
transaction.Rollback();
}
}
With that in mind, you may be able to apply TransactionAttribute to AnotherMethod() and re-throw the exceptions you catch:
[TransactionAttribute]
public void AnotherMethod() {
try {
DoStuff();
}
catch (Exception ex) {
//deal with exception
throw;
}
}
If that is not feasible -- such as if you only want part of the behavior that TransactionAttribute injects -- then you will likely have to make a new TransactionAttribute that injects the behavior you want it to inject. One possibility might be that it looks for try-catch blocks and places commits and rollbacks in the appropriate places, but that could be trickier than the current version.
Shot in the dark here, but...
I am assuming that the transaction behavior is injected by an IoC container, and that it does this by making a proxy when you resolve a ChildClass. Therefore the transaction code runs before\after ChildClass.SomeMethod via the proxy. I'm guessing that the behavior you're seeing is that there is no code injection on BaseClass.SomeMethod, so calling it from ChildClass.AnotherMethod does not involve any proxy code injection, it just goes straight through.
If this is the case, you could use a composition pattern and injection of a BaseClass to solve the problem.
If you resolved the following class via your container, it would inject a proxied BaseClass which had the appropriate before\after transaction code for BaseClass.SomeMethod method. You would therefore get your transaction behavior, plus your graceful exception handling.
You can play around with the usual OO mechanisms to sort out the issue of making AnotherChildClass interchangeable for a BaseClass, or use an interface, etc, etc.
public class AnotherChildClass
{
private readonly BaseClass _bling;
public AnotherChildClass(BaseClass bling)
{
_bling = bling;
}
public void AnotherMethod()
{
try
{
_bling.SomeMethod();
}
catch (Exception)
{
//Do nothing...
}
}
}
For example, a bit urgh, but you get the picture:
public class AnotherChildClass : BaseClass
{
private readonly BaseClass _bling;
public AnotherChildClass(BaseClass bling)
{
_bling = bling;
}
public override void SomeMethod()
{
_bling.SomeMethod();
}
public void AnotherMethod()
{
try
{
_bling.SomeMethod();
}
catch (Exception)
{
//Do nothing...
}
}
}
Update
I'm guessing that from your latest investigations the cases where you have used 'new' are not working as you are now blocking the generated IoC container proxy from overriding SomeMethod and therefore injecting the code. Try creating a derived class of your Child class, and try overriding the new SomeMethod method. This illustrates how the proxy is blocked.
private class BaseClass
{
public virtual void SomeMethod(){}
}
private class ChildClass : BaseClass
{
public new void SomeMethod() //<- Declaring new method will block proxy
{
base.SomeMethod();
}
}
private class ChildClassIocProxy : ChildClass
{
public override void SomeMethod() //<-- Not possible!
{
//Injected - before Tx
base.SomeMethod();
//Injected - after Tx
}
}
I am trying to test the logic from some existing classes. It is not possible to re-factor the classes at present as they are very complex and in production.
What I want to do is create a mock object and test a method that internally calls another method that is very hard to mock.
So I want to just set a behaviour for the secondary method call.
But when I setup the behaviour for the method, the code of the method is invoked and fails.
Am I missing something or is this just not possible to test without re-factoring the class?
I have tried all the different mock types (Strick,Stub,Dynamic,Partial ect.) but they all end up calling the method when I try to set up the behaviour.
using System;
using MbUnit.Framework;
using Rhino.Mocks;
namespace MMBusinessObjects.Tests
{
[TestFixture]
public class PartialMockExampleFixture
{
[Test]
public void Simple_Partial_Mock_Test()
{
const string param = "anything";
//setup mocks
MockRepository mocks = new MockRepository();
var mockTestClass = mocks.StrictMock<TestClass>();
//record beahviour *** actualy call into the real method stub ***
Expect.Call(mockTestClass.MethodToMock(param)).Return(true);
//never get to here
mocks.ReplayAll();
//this is what i want to test
Assert.IsTrue(mockTestClass.MethodIWantToTest(param));
}
public class TestClass
{
public bool MethodToMock(string param)
{
//some logic that is very hard to mock
throw new NotImplementedException();
}
public bool MethodIWantToTest(string param)
{
//this method calls the
if( MethodToMock(param) )
{
//some logic i want to test
}
return true;
}
}
}
}
MethodToMock is not virtual and therefore can't be mocked. What you want to do is possible with a partial mock (I've done it in cases similar to yours), but the method you want to mock out must be either part of an interface implementation or be marked virtual. Otherwise, you can't mock it with Rhino.Mocks.
I recommend not mocking methods in the class under test, but your situation may be unique in that you can't refactor the class to make it easier to test at present. You might try explicitly making a delegate to prevent the method from being invoked when setting up the call.
Expect.Call( delegate { mockTestClass.MethodToMock(param) } ).Return(true);
Or, switch to using the AAA syntax, omitting the deprecated constructs.
[Test]
public void Simple_Partial_Mock_Test()
{
const string param = "anything";
var mockTestClass = MockRepository.GenerateMock<TestClass>();
mockTestClass.Expect( m => m.MethodToMock(param) ).Return( true );
//this is what i want to test
Assert.IsTrue(mockTestClass.MethodIWantToTest(param));
mockTestClass.VerifyAllExpectations();
}