Partial Mock or new class or what else? - unit-testing

I have a question about testing.
I have a class that returns anomalies. in this class I have two different method that simply returns two different types of anomalies and one that return all anomalies (of both types)
this is the example code:
public interface IAnomalyService
{
IList<Anomaly> GetAllAnomalies(object parameter1, object parameter2);
IList<Anomaly> GetAnomalies_OfTypeA(object parameter1);
IList<Anomaly> GetAnomalies_OfTypeB(object parameter2);
}
public class AnomalyService : IAnomalyService
{
public IList<Anomaly> GetAllAnomalies(object parameter1, object parameter2)
{
var lstAll = new List<Anomaly>();
lstAll.AddRange(GetAnomalies_OfTypeA(parameter1));
lstAll.AddRange(GetAnomalies_OfTypeB(parameter2));
return lstAll;
}
public IList<Anomaly> GetAnomalies_OfTypeA(object parameter1)
{
//some elaborations
return new List<Anomaly> { new Anomaly { Id = 1 } };
}
public IList<Anomaly> GetAnomalies_OfTypeB(object parameter2)
{
//some elaborations
return new List<Anomaly> { new Anomaly { Id = 2 } };
}
}
class Anomaly
{
public int Id { get; set; }
}
I've created the tests for the two method that retrieve the anomalies of type A and type B (GetAnomalies_OfTypeA and GetAnomalies_OfTypeB).
Now I want to test the function GetAllAnomalies but I'm not sure what I have to do.
I think I have to way for testing it:
1) declare GetAnomalies_OfTypeA and GetAnomalies_OfTypeB in class AnomalyService as virtual, make a mock of the Class AnomalyService, and using Moq I can set CallBase as true and mock the two method GetAnomalies_OfTypeA and GetAnomalies_OfTypeB.
2)move the method GetAllAnomalies in another class called AllAnomalyService (with interface IAllAnomalyService) and in its constructor I will pass an interface of IAnomalyService and after I can test the GetAllAnomalies mocking the IAnomalyService interface.
I'm new at unit testing, so I don't know which solution is better, if is one of the mines or another one.
Can you help me?
thank you
Luca

Mocking is a good tool when a class resists testing. If you have the source, mocking is often not necessary. Try this approach:
Create a factory which can return AnomalyServices with various, defined anomalies (only type A, only type B, both, none, only type C, ...)
Since the three types are connected in some way, you should check all three in each test. If only anomalies of type A are expected, you should check that GetAllAnomalies returns the same result as GetAnomalies_OfTypeA and GetAnomalies_OfTypeB returns an empty list.

Related

Which pattern to use in order to execute new code by just adding new subclasses of a base class?

I am trying to figure out a pattern to avoid code duplication in a situation similar to the one bellow:
std::list<int> error_list;
void validate()
{
if( validate_0001() == false )
{ error_list.push_back(1); }
if( validate_0002() == false )
{ error_list.push_back(2); }
...
}
The method 'validate' is public in a class responsible for performing different actions, in the example validations, each one with an unique id. I want to be able to add a new action by just extending a base class, without the need to create a new method and add its call and its error handling inside the validate method.
I'm suggesting you use validating decorators (Here is a Java example)
abstract class Validation {
final List<Integer> list;
Validation(List<Integer> list) {
this.list = list;
}
public abstract int error();
}
class FirstValidation extends Validation {
public FirstValidation(List<Integer> list) {
super(list);
}
#Override
public int error() {
return 0;
}
}
You can't really extend a single function from a base class without extending the whole class.
One thing you can do is make the validation methods in a separate class and extend it by the two other classes. Another thing you can do is make the validations as an abstract class and implement it as you please in the child classes,the disadvantage of this approach is that you would have to provide the implementation in each of the child classes.

gmock Multiple mock instances, but only one is effective

I would like to test a class (Controller) that manages a set of entities of a certain kind. Entities are created internally in this class because a factory would be an overkill here, so here is how I inject mocks into it:
class TestController : public Controller {
public:
/* Mechanism for a mock injection */
std::shared_ptr<IEntity> create_entity() override {
return temp_entity;
}
/* Variable to hold the entity being injected */
std::shared_ptr<IEntity> temp_entity;
};
Production code invokes create_entity() in the Controller class, which I overload here, and adds the result to a container. temp_entity is the way I supply my mocks and the test, where I supply two distinct mock instances, looks like this:
class MockEntity : public IEntity {
MOCK_METHOD0(perform_operation, bool());
}
TEST(ControllerTest, TestFailure) {
std::shared_ptr<TestController> controller = std::make_shared<TestController>();
std::shared_ptr<MockEntity> entity1 = std::make_shared<MockEntity>();
controller->temp_entity = entity1;
controller->add_entity(); // This invokation fetches the result of create_entity()
std::shared_ptr<MockEntity> entity2 = std::make_shared<MockEntity>();
controller->temp_entity = entity2;
controller->add_entity(); // This invokation fetches the result of create_entity()
EXPECT_CALL(*entity1, perform_operation().WillOnce(::testing::Return(true));
EXPECT_CALL(*entity2, perform_operation().WillOnce(::testing::Return(false));
controller->run();
}
controller.run() only concurrently executes perform_operation() on each of the entities.
When the test is run, the function in the second expectation is called twice and the function in the first expectation is not run at all. I am sure that the controller operates on two distinct versions of an entity before executing run() function.
Is there a fundamental problem in what I am trying to do? How can I separate my expectations for these two mocks in a test? I tried creating two distinct mock classes with perform_operation() method being implemented in the mock body and when running the test in the debugger I still hit the method of one mock class twice.
The test looks correct and the way, how you inject the mocks into the system under test, is an absolutely reasonable method.
I suppose, the critical issue is in your class under Test. I rebuild your Test with the following controller:
class Controller {
public:
virtual std::shared_ptr<IEntity> create_entity() = 0;
void add_entity() {
auto entity = create_entity();
entities.push_back(entity);
}
void run() {
for(auto e : entities) {
bool i = e->perform_operation();
}
}
std::vector<std::shared_ptr<IEntity> > entities;
};
With this class the test succeeded like expected.

Should the CustomEventArgs method implement another Interface?

Hi I am using test driven development and seem to be in an area I am not familiar. Could you Please check and let me know what changes I should make in my code to make it "unit testable" ?
Code to be tested:
public void PurchaseItemList()
{
//call methods to checkavailablility
If(!productAvailable)
{
purchaseItemEventArgs.IsSuccessfull = false;
}
else
{
purchaseItemEventArgs.IsSuccessfull = true;
// code to update model.
purchaseItemEventArgs.ItemsPurchased = GetItemsPurchased()
}
}
Now the issue I face is that I cannot mock the purchaseItemEventArgs class as it does not implement any interface. I am using moq for testing. Any advise on the code changes to make it unit testable would be very helpfull.
Thanks
Since GetItemsPurchased() is a method of your class, you could make it protected virtual. So you could then define a test class like this:
class TestableMyClass : MyClass{
private Items _items;
public TestableMyClass(Items items) : base() {
_items = items;
}
protected Items GetItemsPurchased(){
return _items;
}
}
And then, in your tests, replace new MyClass by new TestableMyClass(myItems).
This way, your actual GetItemsPurchased() won't be called in your tests, and you can inject the items you want.

Unit Testing abstract classes and or interfaces

I'm trying to start using Unit Testing on my current project in Visual Studio 2010. My class structure, however, contains a number of interface and abstract class inheritance relationships.
If two classes are derived from the same abstract class, or interface I'd like to be able to share the testing code between them. I'm not sure how to do this exactly. I'm thinking I create a test class for each interface I want to test, but I'm not sure the correct way to feed my concrete classes into the applicable unit tests.
Update
OK here's an example. Say I have an interface IEmployee , which is implemented by an abstract class Employee, which is then inherited by the two concrete classes Worker and Employee. (Code show below)
Now say I want to create tests that apply to all IEmployees or Employees. Or alternatively create specific tests for specific types of Employees. For example I may want to assert that setting IEmployee.Number to a number less then zero for any implementation of IEmployee throws an exception. I'd prefer to write the tests from the perspective of any IEmployee and then be able to use the tests on any implementation of IEmployee.
Here's another example. I may also want to assert that setting the vacation time for any employee to a value less then zero throws and error. Yet I may also want to have different tests that apply to a specific concrete version of Employee. Say I want to test that Worker throws an exception if they are provided more then 14 days vacation, but a manager can be provided up to 36.
public interface IEmployee
{
string Name {get; set;}
int Number {get; set;}
}
public abstract class Employee:IEmploee
{
string Name {get; set;}
int Number {get;set;}
public abstract int VacationTime(get; set;)
}
public abstract class Worker:IEmployee
{
private int v;
private int vTime;
public abstract int VacationTime
{
get
{
return VTime;
}
set
{
if(value>36) throw new ArgumentException("Exceeded allowed vaction");
if(value<0)throw new ArgumentException("Vacation time must be >0");
vTime= value;
}
}
public void DoSomWork()
{
//Work
}
}
public abstract class Manager:IEmployee
{
public abstract int VacationTime
{
get
{
return VTime;
}
set
{
if(value>14) throw new ArgumentException("Exceeded allowed vaction");
if(value<0)throw new ArgumentException("Vacation time must be >0");
vTime= value;
}
}
public void DoSomeManaging()
{
//manage
}
}
So I guess what I'm looking for is a work flow that will allow me to nest unit tests. So for example when I test the Manager class I want to first test that it passes the Employee and IEmployee tests, and then test specific members such as DoSomeManaging().
I guess I know what you mean. I had the same issue.
My solution was to create a hierarchy also for testing. I'll use the same example you show.
First, have an abstract test class for the base IEmployee.
It has two main things:
i. All the test methods you want.
ii. An abstract method that returns the desired instance of the IEmployee.
[TestClass()]
public abstract class IEmployeeTests
{
protected abstract GetIEmployeeInstance();
[TestMethod()]
public void TestMethod1()
{
IEmployee target = GetIEmployeeInstance();
// do your IEmployee test here
}
}
Second, you have a test class for each implementation of IEmployee, implementing the abstract method and providing appropriate instances of IEmployee.
[TestClass()]
public class WorkerTests : IEmployeeTests
{
protected override GetIEmployeeInstance()
{
return new Worker();
}
}
[TestClass()]
public class ManagerTests : IEmployeeTests
{
protected override GetIEmployeeInstance()
{
return new Manager();
}
}
You can see everything works as expected and VS gives you the expected test methods for each WorkerTests and ManagerTests classes in the TestView window.
You can run them and have the test results for each implementation of the IEmployee interface, having to create the tests only in the base IEmployeeTests class.
You can always add specific test for the derived WorkerTests and ManagerTests classes.
The question would be now, what about classes that implement multiple interfaces, let's say EmployedProgrammer?
public EmployedProgrammer : IEmployee, IProgrammer
{
}
We don't have multiple inheritance in C#, so this is not an option:
[TestClass()]
public EmployedProgrammerIEmployeeTests : IEmployeeTests, IProgrammerTests
{
// this doesn't compile as IEmployeeTests, IProgrammerTests are classes, not interfaces
}
For this scenario, a solution is to have the following test classes:
[TestClass()]
public EmployedProgrammerIEmployeeTests : IEmployeeTests
{
protected override GetIEmployeeInstance()
{
return new EmployedProgrammer();
}
}
[TestClass()]
public EmployedProgrammerIProgrammerTests : IProgrammerTests
{
protected override GetIProgrammerInstance()
{
return new EmployedProgrammer();
}
}
with
[TestClass()]
public abstract class IProgrammerTests
{
protected abstract GetIProgrammerInstance();
[TestMethod()]
public void TestMethod1()
{
IProgrammer target = GetIProgrammerInstance();
// do your IProgrammerTest test here
}
}
I'm using this with good results.
Hope it helps.
Regards,
Jose
What I think you want to do is create unit tests for methods in abstract classes.
I'm not sure it makes sense to want to test a protected method on an abstract class, but if you insist simply extend the class in a class used exclusively for unittesting. That way you can expose the protected methods on the abstract class you want to test through public methods on the extending class that simply call through to the method on the abstract class.
If you have methods in abstract classes that you want unittested, I suggest refactoring them into separate classes and simply expose them as public methods and put those under test. Try looking at your inheritance tree from a 'test-first' perspective and I'm pretty sure you'll come up with that solution (or a similar one) as well.
It seems that you have described "composite unit testing" which is not supported by Visual Studio 2010 unit tests. Such things can be done in MbUnit according to this article. It is possible to create abstract tests in Visual Studio 2010 which is probably not exactly what you want. Here is description how to implement abstract tests in VS (Inheritance Example section).
Use microsoft moles for better testing. so you can mock the abstract base class / static methods etc easily. Please refer the following post for more info
detouring-abstract-base-classes-using-moles
BenzCar benzCar = new BenzCar();
new MCar(benzCar)
{
Drive= () => "Testing"
}.InstanceBehavior = MoleBehaviors.Fallthrough;
var hello = child.Drive();
Assert.AreEqual("Benz Car driving. Testing", hello);
The desire to run the same test against multiple classes usually means you have an opportunity to extract the behavior you want to test into a single class (whether it's the base class or an entirely new class you compose into your existing classes).
Consider your example: instead of implementing vacation limits in Worker and Manager, add a new member variable to Employee, 'MaximumVacationDays', implement the limit in the employee class' setter, and check the limit there:
abstract class Employee {
private int maximumVacationDays;
protected Employee(int maximumVacationDays) {
this.maximumVacationDays = maximumVacationDays
}
public int VacationDays {
set {
if (value > maximumVacationDays)
throw new ArgumentException("Exceeded maximum vacation");
}
}
}
class Worker: Employee {
public Worker(): Employee(14) {}
}
class Manager: Employee {
public Manager(): Employee(36) {}
}
Now you have only one method to test and less code to maintain.

Should class methods accept parameters or use class properties

Consider the following class
public class Class1
{
public int A { get; set; }
public int B { get; set; }
public int GetComplexResult()
{
return A + B;
}
}
In order to use GetComplexResult, a consumer of this class would have to know to set A and B before calling the method. If GetComplexResult accesses many properties to calculate its result, this can lead to wrong return values if the consumer doesn't set all the appropriate properties first. So you might write this class like this instead
public class Class2
{
public int A { get; set; }
public int B { get; set; }
public int GetComplexResult(int a, int b)
{
return a + b;
}
}
This way, a caller to GetComplexResult is forced to pass in all the required values, ensuring the expected return value is correctly calculated. But if there are many required values, the parameter list grows as well and this doesn't seem like good design either. It also seems to break the point of encapsulating A, B and GetComplexResult in a single class. I might even be tempted to make GetComplexResult static since it doesn't require an instance of the class to do its work. I don't want to go around making a bunch of static methods.
Are there terms to describe these 2 different ways of creating classes? They both seem to have pros and cons - is there something I'm not understanding that should tell me that one way is better than the other? How does unit testing influence this choice?
If you use a real-world example the answer becomes clearer.
public class person
{
public string firstName { get; set; }
public string lastName { get; set; }
public string getFullName()
{
return firstName + " " + lastName;
}
}
The point of an entity object is that it contains information about an entity, and can do the operations that the entity needs to do (based on the information it contains). So yes, there are situations in which certain operations won't work properly because the entity hasn't been fully initialized, but that's not a failure of design. If, in the real world, I ask you for the full name of a newborn baby who hasn't been named yet, that will fail also.
If certain properties are essential to an entity doing its job, they can be initialized in a constructor. Another approach is to have a boolean that checks whether the entity is in a state where a given method can be called:
while (person.hasAnotherQuestion()) {
person.answerNextQuestion();
}
A good design rule is to make sure that all constructors initializes objects to valid states and that all property setters and methods then enforces the valid state. This way there will never be any objects in invalid states.
If the default values for A and B, which is 0 is not a valid state that yields a valid result from GetComplexResult, you should a constructor that initialized A and B to valid a state.
If some of the fields are never allowed to be null then you would typically make them parameters to the class constructor. If you don't always have all of the required values available at once then using a builder class may be helpful.
For example:
public Builder {
private int a;
private int b;
public Class1 create() {
// some validation logic goes here
// to make sure we have everything and
// either fill in defaults or throw an error
// if needed
return new Class1(a, b)
}
public Builder a(int val) { a = val; }
public Builder b(int val) { b = val; }
}
This Builder can then be used as follows.
Class1 obj1 = new Builder().a(5).b(6).create();
Builder builder = new Builder();
// do stuff to find value of a
builder.a(valueOfA);
// do stuff to find value of b
builder.b(valueOfB);
// do more stuff
Class1 obj2 = builder.create();
Class2 obj3 = builder.create();
This design allows you to lock down the Entity classes to whatever degree is appropriate while still allowing for a flexible construction process. It also opens the door to customizing the construction process with other implementations without changing the entity class contract.