Unit Testing with Rhino Mocks - unit-testing

I have the following method called Execute() from the Abstract class called AutoLetterGenBatch in my ConsoleApp. I am trying to unit test this.
public void Execute()
{
BatchJobSecurity.Instance.CreatePrincipal();
DoExecute();
}
So I set up what I believe are all the proper references and try to invoke the method like below .
[TestMethod]
public void TestMethod1()
{
AutoLetterGenBatchJob ALGBJ = new AutoLetterGenBatchJob();
ALGBJ.Execute();
}
However, when I go to do the build it gives me this compilation error Error 34 Cannot create an instance of the abstract class or interface 'AutoLetterGenBatch.AutoLetterGenBatchJob' .
I am somewhat new to unit testing. I realize this probably isn't much of a test but I just want to see my Execute() method get hit for the time being. I have read that a good way to get around this problem with abstract classes is to set up a mock object for the abstract class. So I try to do this with RhinoMocks.
[TestMethod]
public void TestMethod1()
{
AutoLetterGenBatchJob ALGBJ = MockRepository.GenerateStub<AutoLetterGenBatchJob>();
ALGBJ.Execute();
}
It now builds with all of the proper using statements in place. However when the test runs I now get this error. Can't find a constructor with matching arguments . Again I am pretty new to this. If someone can help me to understand what it is I need to do it would be appreciated.

YOur first test doesn't make any sense, your class is abstract, by definition you can't create an instance of it. In order to test that method you need a class which derives from AutoLetterGenBatch and you then create an instance of this class and do what is neccessary to invoke the method on this instance.
Using a mocking framework would be one way, as would creating a test class of your own. Personally I would go with the 'roll your own' at first as this will be easier to debug.
public class TestAutoLetterGenBatch : AutoLetterGenBatch
{
}
once you have this class you'll see that you need to call the constructor that AutoLetterGenBatch declares. This is the same issue that rhino mocks it complaining about. Without seeing the class AutoLetterGenBatch we can't advise any further.
For what it is worth, Rhino mocks has seen little work recently and you would probably be better using Moq or another more active framework.
Also you need to generate a partial mock to do the testing you want to do, no a stub.

Related

Can method call be tested without Mockito.verify?

If i need to test if a method within class under test has been called or not, can it be done without Mockito (or any mocking tool for that matter)?
Reason asking is that wherever i read about Mockito and similar tools, it says one should never mock CUT but its dependencies (that part is clear).
So, if thats the case then there are only 2 options left:
there is some other way of testing it without mocking
or
the fact the method was called should not be tested itself but some side effect or methods return value
For example (trivial and non-realworld), class MyClass can have 2 methods: A() and B(). A conditionay calls B based on some internal state.
After arranging state & acting by calling A() we want to assert that B() was called.
Either its not possible without mocking the whole CUT or 2 methods like this in a single class are always SRP violation smell and call for redesign where B() should actually be (mocked) dependency of MyClass CUT.
So, whats correct?
Usually I tend to not even use spies, instead I prefer to write my code in a way that for any class I write:
I test only non-private methods, since they're entry points into the class under test. So, in your example, if a() calls b(), maybe b() should be be private and, as a consequence, should not be tested. To generalize, a() is something that a class "can do" (a behavior), so I test the behavior, and not the method itself. If this behavior internally calls other things - well, its an internal matter of that class, if possible I don't make any assumptions on how does the class work internally, and always prefer "white-box" testing.
I only test "one" non-private method in a test.
All the methods should return something (best option) or at least call dependencies, or change internal state of the object under test. The list of dependencies is always clean-to-understand, I can't instantiate the object of CUT without supplying it a list of dependencies. For example, using constructor dependency injection is a good way of doing this. I mock only dependencies indeed, and never mock / spy CUT. Dependencies are never static but injected.
Now with these simple rules, the need to "test if a method within class under test has been called or not" basically can boil down to one of the following:
you're talking about private method. In this case - don't test it, test only public things.
The method is public - in this case you explicitly call it in unit test, so its irrelevant.
Now lets ask why do you want to test this if a method within CUT has been called or not?
If you want to make sure that it changed something. If this "something" is within the class - in other words, its internal state has changed, check in test that the change is indeed done in the state by calling another method that allows to query the state
If this "something" is a code that is managed by dependency, create a mock of this dependency and verify that it was called with the expected parameters.
Take a look at the Mockito Documentation (https://static.javadoc.io/org.mockito/mockito-core/3.0.0/org/mockito/Mockito.html#13)
When using a Spy you can 'replace' a method in the same class that is under test.
#ExtendWith(MockitoExtension.class)
public class Test {
class MyClass {
public void a() {
b();
}
public void b() {
}
}
#Test
public void test() {
MyClass testClass = new MyClass();
MyClass spy = Mockito.spy(testClass);
Mockito.doNothing().when(spy).b();
spy.a();
Mockito.verify(spy, Mockito.times(1)).b();
}
}
So whether that is something that should be done is a different question ;)
I think it highly depends on what method B() is actually doing and whether that is supposed be part of MyClass in the first place.
Either its not possible without mocking the whole CUT
In this case we do not mock the whole CUT only the method you do not want to be called.
Reason asking is that wherever i read about Mockito and similar tools, it says one should never mock CUT but its dependencies (that part is clear).
I believe this statement is not entirely accurate in correlation with spying.
The whole point of spying in my eyes is to use it on the class under test. Why would one want to spy on a dependecy that is not even supposed to be part of the test in the first place?

unit-test the template method design pattern

Suppose the following template method implementation:
public abstract class Abs
{
void DoYourThing()
{
log.Info("Starting");
try
{
DoYourThingInternal();
log.Info("All done");
}
catch (MyException ex)
{
log.Error("Something went wrong here!");
throw;
}
}
protected abstract void DoYourThingInternal();
}
Now, there are plenty of info around on how to test the Abs class, and make sure that DoYourThingInternal is called.
However, suppose I want to test my Conc class:
public class Conc : Abs
{
protected override void DoYourThingInternal()
{
// Lots of awesome stuff here!
}
}
I wouldn't want to do conc.DoYourThing(), since this will invoke the parent method, which was already tested separately.
I would like to test only the overriding method.
Any ideas?
You have labeled the question "tdd" but I doubt you've followed that principle when you encountered this "problem".
If you truly followed tdd your work flow would have been something like
Write a test for some logic not yet implemented
Impl the easiest possible impl for this test to make it green (logic on Conc1 for example)
Refactor
Write a test for some other logic not yet implemented
Impl the easiest possible impl for this test to make it green (logic on Conc2 for example)
Refactor
In "6" you might think that it would be a great idea to implement a template method because Conc1 and Conc2 share some logic. Just do it, and run your tests to see that the logic still works.
Write tests to verify the logic, don't base them how the implementation look like (=start with the tests). In this case, start writing tests verifying that the logic works (the logic later placed in your concrete types). Yes, that means that some code lines (the one in your abstract class) are tested multiple times. But so what? One of the point of writing tests is that you should be able to refactor your code but still be able to verify that it works by running your tests. If you later don't want to use template method pattern, in a ideal world your shouldn't need to change any tests, but just change the implementation.
If you start to think which code lines you test, IMO you loose much of the benefits of writing tests at all. You want to ensure that your logic works - write tests for this instead.
I assume part of the 'problem' is that there is no way to call a protected method from outside the class. How about a mock class which derives from Conc and provides a new public method:
public class MockConc: Conc
{
void MockYourThingInternal()
{
DoYourThingInternal()
}
}
I wouldn't consider DoYourThingInternal() to be separate from DoYourThing() (as in, two separate modules of code that can be tested in isolation) since you won't be able to instantiate your abstract class alone anyways and the 2 methods will always be run together. Besides, DoYourThingInternal() has access to all protected members of your class and could modify them, with potential side effects on DoYourThing(). So I think it would be dangerous to test DoYourThing() in complete isolation from a concrete implementation of DoYourThingInternal().
However, that doesn't mean you can't have separate tests for DoYourThing()'s expected behavior, which has to remain the same across all implementations of Abs, and DoYourThingInternal()'s expected behavior.
You could use an (abstract) base test class where you define a test for the general behavior expected from DoYourThing(). Then create as many test subclasses as there are implementations of Abs, with unit tests for the specifics of each implementation.
The test from the base test class will be inherited, and when you run any subclass's tests, the inherited test for DoYourThing() will also run :
public abstract class AbsBaseTest
{
public abstract Abs GetAbs();
[Test]
public void TestSharedBehavior()
{
getAbs().DoYourThing();
// Test shared behavior here...
}
}
[TestFixture]
public class AbsImplTest : AbsBaseTest
{
public override Abs GetAbs()
{
return new AbsImpl();
}
[Test]
public void TestParticularBehavior()
{
getAbs().DoYourThing();
// Test specific behavior here
}
}
See http://hotgazpacho.org/2010/09/testing-pattern-factory-method-on-base-test-class/
Don't know if abstract test class inheritance is supported by all unit test frameworks though (I think NUnit does).
What about sticking an interface on Abs and mocking it? Ignoring the calls, or set expectations on them?
You could do it several ways, many of which are documented here already. Here is the approach I typically take: Have the test case inherit from the concrete class.
public ConcTest : Conc
{
[Test]
public void DoesItsThingRight()
{
var Result = DoItsThingInternal();
// Assert the response
}
}
Hope that helps!
Brandon

Where should I test methods on an abstract class?

I have an abstract class that defines some methods. This class has two subclasses.
Should I create a fake subclass just for testing, or should I test the methods through the subclasses' tests? Testing through the subclasses seems more natural, but then I'd have to duplicate the test code between the 2 subclasses' tests.
What do you guys think?
You don't have to duplicate your test code - you can write your test methods so that they accept a parameter.
Since most test frameworks don't support tests that take parameters you can add a little wrapper that calls your parameterized test method with a specific instance. You can now easily choose whether it makes sense to call your test just once with some specific base class, or have multiple tests of the same method - one test for each of the possible base classes. Since only a thin wrapper needs to be added for each new test, there is very little code duplication.
void TestSomething(AbstractClass foo)
{
// Your test code goes here.
Assert.AreEqual(42, foo.Bar());
}
[Test]
void TestSomethingFoo1()
{
TestSomething(new Foo1());
}
[Test]
void TestSomethingFoo2()
{
TestSomething(new Foo2());
}
I would go for a minimal fake subclass, associating this with the Abstract Class. I like to think that the Abstract class is properly tested no matter what happens to any of the Concrete instantiations. This does assume that the code in the Abstract class is non-trivial and writing the fake class is not dispropoartionate work - with mocks I think this will usually be the case.

Do I need to write a unit test for a method within service class that only calls a method within repository class?

Example
I have a repository class (DAL):
public class MyRepository : IMyRepository
{
public void Delete(int itemId)
{
// creates a concrete EF context class
// deletes the object by calling context.DeleteObject()
}
// other methods
}
I also have a service class (BLL):
public class MyService
{
private IMyRepository localRepository;
public MyService(IMyRepository instance)
{
this.localRepository = instance;
}
public void Delete(int itemId)
{
instance.Delete(itemId);
}
// other methods
}
Creating a unit test for MyRepository would take much more time than implementing it, because I would have to mock Entity Framework context.
But creating a unit test for MyService seems nonsense, because it only calls into Repository. All I could check is to verify if it did actually call repository Delete method.
Question
How would you suggest to unit test these pair of Delete methods. Both? One? None? And what would you test?
Yes, I would definitely write a unit test for the Service Layer. The reason for this is because, you're not just testing that your implementation works now, but you're also testing that it will continue to work in the future.
This is a vital concept to understand. If someone comes along later on and changes your ServiceLayer, and there's no unit test, how can you verify that the functionality continues to work?
I would also write tests for your DAL, but I would put those in a separate assembly called DataTests or something. The purpose here is to isolate your concerns across assemblies. Unit Tests shouldn't be concerned with your DAL, really.
Yes, both.
IMyRepository mock = ...;
// create Delete(int) expectation
MyService service = new MyService(mock);
service.Delete(100);
// Verify expectations
Your Delete method right now might only call the Delete method on the repository, but that doesn't mean it always will. You want to have unit tests for this partly to verify it behaves correctly and partly as way of defining your specifications of how the repository is to work.
You also aught to have a test that verifies that the constructor will throw an exception if the repository is null. You might also have other validation to do here in this method such as non-negative ID's, or non-zero id. Maybe that doesn't happen here, make it part of the specifications by creating tests that verify the expected behaviors.
They seem trivial but I can all but guarantee it will change one day and your expectation and specifications may not be verified.
Create the test for the Service. Currently all it does is to call into the Repository Delete method; however, you shouldn't care about that. What if later something happens and the functionality becomes much more complicated? Don't you want to have unit test code that will assure you that the functionality is still working as expected?
If you're exposing your Delete through your Service, you're expecting it to have an effect. Write a Unit Test to test that effect. Depending on your particular needs, I'd say you might not need to have a test on the Repository Delete, particularly if that functionality is getting exercised as part of your Service Delete functionality, but it really all depends on what level of coverage you're trying for.
Also, if you had created this code with TDD, you would have had a test. It actually matters whether people can call Delete through your service, so you actually have to test it.
In my opinion you need to test both. Maybe you can do the creation EF context class in a seperate factory that can be tested more easy and mock the context class for the MyRepository tests. That will be more easy and using a factory for creating a context calls seems to be quiet useful for me.

Rhino Mocks - How can I test that at least one of a group of methods is called?

Say I have an interface IFoo which I am mocking. There are 3 methods on this interface. I need to test that the system under test calls at least one of the three methods. I don't care how many times, or with what arguments it does call, but the case where it ignores all the methods and does not touch the IFoo mock is the failure case.
I've been looking through the Expect.Call documentation but can't see an easy way to do it.
Any ideas?
You can give rhino mocks a lambda to run when a function get's called. This lambda can then increment a counter. Assert the counter > 1 and you're done.
Commented by Don Kirkby:
I believe Mendelt is referring to the Do method.
Not sure this answers your question but I've found that if I need to do anything like that with Rhino (or any similiar framework/library), anything that I didn't know how to do upfront, then I'm better just creating a manual mock.
Creating a class that implements the interface and sets a public boolean field to true if any of the methods is called will be trivially easy, you can give the class a descriptive name which means that (most importantly) the next person viewing the code will immediately understand it.
If I understood you correctly you want to check that the interface is called at least once on any of three specified methods. Looking through the quick reference I don't think you can do that in Rhino Mocks.
Intuitively I think you're trying to write a test that is brittle, which is a bad thing. This implies incomplete specification of the class under test. I urge you to think the design through so that the class under test and the test can have a known behavior.
However, to be useful with an example, you could always do it like this (but don't).
[TestFixture]
public class MyTest {
// The mocked interface
public class MockedInterface implements MyInterface {
int counter = 0;
public method1() { counter++; }
public method2() { counter++; }
public method3() { counter++; }
}
// The actual test, I assume you have the ClassUnderTest
// inject the interface through the constructor and
// the methodToTest calls either of the three methods on
// the interface.
[TestMethod]
public void testCallingAnyOfTheThreeMethods() {
MockedInterface mockery = new MockedInterface();
ClassUnderTest classToTest = new ClassUnderTest(mockery);
classToTest.methodToTest();
Assert.That(mockery.counter, Is.GreaterThan(1));
}
}
(Somebody check my code, I've written this from my head now and haven't written a C# stuff for about a year now)
I'm interested to know why you're doing this though.