I work with a distributed system that has unit and integration tests. I am trying to save time and maintenance efforts by reusing code between integration and unit tests. For this I implemented an interface and 2 classes: fake and real. Fake class returns some stubbed data, and real class makes a few calls to other distributed services.
Current structure of my projects
/BaseTest interface IFoo ------------------------------------- /UnitTest class FakeFoo : IFoo [TestFixture] class FooTest {...} //uses FakeFoo ------------------------------------- /IntegrationTest class RealFoo : IFoo [TestFixture] class FooTest {...} //uses RealFoo
I want to somehow reuse code for both tests, so if I have a test
[Test]
public void GetBarIsNotNullTest()
{
var foo = IoC.Current.Resolve<IFoo>();
Bar actual = foo.GetBar();
Assert.IsNotNull(actual);
}
I want this test to run with both implementations: RealFoo
and FakeFoo
. So far I thought about copy-pasting tests between /UnitTest and /IntegrationTest projects, but this doesn't sound right.
System is written in C#, but I believe this question is language agnostic.
Anyone has better ideas? Am I doing this wrong?
Unit Testing is a kind of white box testing, whereas Integration Testing is a kind of black-box testing. For Unit Testing, accessibility of code is required, as it tests the written code, while for Integration Testing, access to code is not required, since it tests the interactions and interfaces between modules.
The most common problem I see with integration testing is that most attempts at integration testing do not recognize that people “using” the system have different expectations of the system, and will use the “integrations” differently depending on those expectations and their business needs.
Separating things Usually unit tests are fast and even if you run them by mistake, you won't feel uncomfortable. Integration, contract and acceptance tests can take several minutes if the project is huge. That's why it makes sense to separate integration and unit tests.
Integration tests are harder to write. Unit tests can be run in any order, or even simultaneously. Integration tests usually required a strict order and can't be run simultaneously.
Even though others had good points in their answers, this is what I ended up doing
I created a base class for unit and integration tests
[TestFixture]
public class FooBase
{
[Test]
public void GetBarIsNotNullTest()
{
var foo = IoC.Current.Resolve<IFoo>();
Bar actual = foo.GetBar();
Assert.IsNotNull(actual);
}
//many other tests
}
And then two derived classes from the FooBase
. These class will only have the SetUp
and nothing else. i.e.:
[TestFixture]
public class UnitTestFoo : FooBase
{
[SetUp]
public void SetUp()
{
IoC.Current.Register<IFoo, FakeFoo>();
}
//nothing else here
}
[TestFixture]
public class IntegrationTestFoo : FooBase
{
[SetUp]
public void SetUp()
{
IoC.Current.Register<IFoo, RealFoo>();
}
//nothing else here
}
So if I now run my tests, I get the tests defined in the parent class FooBase
run twice for unit tests class and integration tests class with their own real and fake objects. This works because of the inheritance of the test fixtures.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With