In my interface
public IMyListInterface : IList<IMyItem>
{
void Foo();
}
how can I easily create an example for testing classes that use IMyListInterface.
Currently I'm using GenerateStub<MyListInterface>() and delegating the needed methods / properties to a List<IMyItem> list but it's tedious.
Currently to get the following code under test to work
foreach (var match in matchList)
I'm doing the following in my test class
IList<IMyItem> baseList = new List<IMyItem>();
IMyListInterface matchList = MockRepository.GenerateStub<IMyListInterface>();
matchList.Stub(m => m.GetEnumerator()).Return(null).WhenCalled(i => i.ReturnValue = baseList.GetEnumerator());
Is there a better way?
Implement the interface in an abstract base class for testing:
public abstract MyMockableList : List<MyItem>, IMyListInterface
{
public abstract void Foo();
}
You can then use MockRepository.GenerateStub<MyMockableList>(), which will function as a normal list (RhinoMocks won't override the methods inherited from List<MyItem>) but you can still stub out the Foo() method.
Related
This question is more like open discussion. I would like to start with an example. Suppose there is one service FooService
public interface IFooService { void Method1(){}}
public class FooService: IFooService { void Method1(){ ... }}
In order to test the service , we write the unit test code like below, no external services
public void TestMethod1(){ ... }
Then suppose in Method1 we need to use another class called AService which inherit from IAService
public interface IAService {void AMethod1(){}}
public class AService : IAService { void AMethod1() {}}
public class FooService : IFooService {
private IAService a;
public FooService (IAService a){ this.a = a;}
void Method1(){ a.AMethod1(); ..... business logic ..... }
}
Then we have to refactor the unit test to mock AService
public void TestMethod1(){
IMockAService aService = MockRepository.StrickMock<IAService>();
.....
}
So when need more external services, we have to add mock service, if some of services changed the logic or add or remove parameters, and so on. If there are 100 test cases, we have to modify all of test cases.
So what's the best solution for mocking increasing external services and effective way to handle any changes of external dependencies for example : add/remove parameters of methods.
thanks
Most times for me it's enough to create the class under test in a Setup method, leaving you with only one place to adapt when the constructor signature changes.
Alternatively you can move construction of the class under test to a private method.
Same goes for methods. Often you can wrap the call to a method under test in a private method. This is especially helpful, if you don't have to set up all passed parameters in every test, but can use defaults, which you might have prepared in your Setup method.
I am looking for a solution to mock the super call in subclass ButtonClicker.
Class Click {
public void buttonClick() throws java.lang.Exception { /* compiled code */ } }
Class ButtonClicker extends Click {
#Override
public void buttonClick() throws Exception {
super.buttonClick();
} }
Using inheritance reduces testability of your code. Consider replacing inheritance with the delegation and mock the delegate.
Extract the interface IClicker
interface IClicker {
void buttonClick();
}
Implement IClicker in Clicker class. In case that you are working with third-party code consider using Adapter Pattern
Rewrite your ButtonClicker as following:
class ButtonClicker implements IClicker {
Clicker delegate;
ButtonClicker(Clicker delegate) {
this.delegate = delegate;
}
#Override
public void buttonClick() throws Exception {
delegate.buttonClick();
}
}
Now just pass the mock as a constructor parameter:
Clicker mock = Mockito.mock(Clicker.class);
// stubbing here
ButtonClicker buttonClicker = new ButtonClicker(mock);
The answer is no. A mock is only a trivial interface implementation. (I mean interface in the API sense, not the specific Java keyword sense.) So it doesn't know about any implementation details like which class actually implements the functionality (there is no functionality, essentially).
You can create a 'spy' on a real object that will let you mock only some methods and not others, but that also will not let you mock just the super method of a class because the method(s) you choose to mock are typically chosen by the signature, which is the same for both the sub class and the super class.
Can anyone help me with this? basically I have a test class, wihtin this test class I have a number of methods which all use the same type of setup. Let me show you by example:
class Test:public CxxTest::TestSuite
{
public:
void Test1(){/*...*/}
void Test2(){/*...*/}
};
Each test method requires the same type of setup:
Class c_objectName = AnotherClass::method("c_name","c_name","c_name");
class c_newObjectName = AnotherCLass::create(c_objectName);
I am currently setting this in every single method, because each of the above i started with "c_..." needs to be different.
I tried to make a "global method" that would take in a string to rename these each time, but then I cant seems to access them from the method calls. I tried the following:
class Test:public CxxTest::TestSuite
{
public:
void method()
{ Class c_objectName = AnotherClass::method("c_name","c_name","c_name"); <--- cant access these
Class c_newObjectName = AnotherClass::create(c_objectName);
}
void Test1(){/*...*/}
void Test2(){/*...*/}
};
Is there a way to put this in a "global method" of some sort so that I can access these from the methods?
Im really bad at explaining things so sorry and thanks in advance
I can't make heads and tails of the question, but it looks like something like this would help:
struct TestFixture
{
Class c_objectName;
Class c_newObjectName;
};
TestFixture makeFixture()
{
TestFixture fixture;
fixture.c_objectName = new Class("c_name","c_name","c_name");
fixture.c_newObjectName = create(c_objectName);
return fixture;
}
(assuming your Class (classes?) are copyable. If not, return a pointer to a new instance of TestFixture or something like scoped_ptr
Then you could use it in your test methods:
void Test1()
{
TestFixture fixture = makeFixture();
// use fixture.c_objectName etc.
If you don't mind sharing the data, you could just make them fields of class Test.
Edit Oh, I just realized you are using CxxTest, which probably has a better way of creating fixtures/setup/teardown for unit tests. However, the above approach should work in any framework.
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.
I am trying to unit test an action filter I wrote. I want to mock the HttpClientCertificate but when I use MOQ I get exception. HttpClientCertificate doesnt have a public default constructor.
code:
//Stub HttpClientCertificate </br>
var certMock = new Mock<HttpClientCertificate>();
HttpClientCertificate clientCertificate = certMock.Object;
requestMock.Setup(b => b.ClientCertificate).Returns(clientCertificate);
certMock.Setup(b => b.Certificate).Returns(new Byte[] { });
This is the most awkward case of creating unit testable systems in .NET. I invariable end up adding a layer of abstraction over the component that I can't mock. Normally this is required for classes with inaccessible constructors (like this case), non-virtual methods or extension methods.
Here is the pattern I use (which I think is Adapter pattern) and is similar to what MVC team has done with all the RequestBase/ResponseBase classes to make them unit testable.
//Here is the original HttpClientCertificate class
//Not actual class, rather generated from metadata in Visual Studio
public class HttpClientCertificate : NameValueCollection {
public byte[] BinaryIssuer { get; }
public int CertEncoding { get; }
//other methods
//...
}
public class HttpClientCertificateBase {
private HttpClientCertificate m_cert;
public HttpClientCertificateBase(HttpClientCertificate cert) {
m_cert = cert;
}
public virtual byte[] BinaryIssuer { get{return m_cert.BinaryIssuer;} }
public virtual int CertEncoding { get{return m_cert.CertEncoding;} }
//other methods
//...
}
public class TestClass {
[TestMethod]
public void Test() {
//we can pass null as constructor argument, since the mocked class will never use it and mock methods will be called instead
var certMock = new Mock<HttpClientCertificate>(null);
certMock.Setup(cert=>cert.BinaryIssuer).Returns(new byte[1]);
}
}
In your code that uses HttpClientCertificate you instead use HttpClientCertificateBase, which you can instantiate like this - new HttpClientCertificateBase(httpClientCertificateInstance). This way you are creating a test surface for you to plug in mock objects.
The issue is that you need to specify constructor parameters when creating the mock of the HttpClientCertificate.
var certMock = new Mock<HttpClientCertificate>(ctorArgument);
The bad news is that the ctor for HttpClientCertificate is internal and takes in an HttpContext, so it probably won't work.
Unless you want to write more code to make the class "Testable" I suggest you use Typemock Isolator, Unless specified otherwise it looks for the first c'tor available - public, internal or private and fake (mocks) it's parameters so you won't have to.
Creating the fake object is as simple as:
var fakeHttpClientCertificate = Isolate.Fake.Instance<HttpClientCertificate>();
Another alternative is to use the free Microsoft Moles framework. It will allow you to replace any .NET method with your own delegate. Check out the link as it gives an example that is pretty easy to understand. I think you'll find it much nicer than adding layers of indirection to get HttpClientCertificate into a testable state.