How to test some method from this interface using NUnit, but do only 1 unit test for all classes?
As you wrote this, people can interpret it as a “single unit test, period”. This, of course, is a very bad idea.
Ideally, you want to make only one statement for each test case, and you really need to assert all the different parts of the logic in your code. Each class will have more than one part of the logic, and each implementation of your interface is a completely different part of the logic (even if it has the same interface and even if you copy and paste the code).
So, you are faced with one of the options: you need some unit tests.
Code duplication
To avoid duplication of unit test code, you can try the parameterized functions of unit test NUnit.
With it, you can multiply the number of unit test methods that you actually write by the number of instances you submitted to these tests. These instances may be different implementations.
There are many ways to parameterize your tests in NUnit. See this article:
I personally prefer the TestCaseSource attribute:
The NUnit tester will still display every unit test method you wrote, but will display every element in your dataset as a subtest.
It's hard to figure out how to use it because you need to test your data-driven model.
How to parameterize an implementation
If your implementations of this method in your interface just spit out different data, you might be lucky. For instance. if you test multiplication in one implementation and addition in another method, your matrix may look like this:
Impl Input1 Input2 Result Multiply 0 7 0 Multiply 3 6 18 Add 0 0 0 Add 5 6 11
You will return an array that embodies each row in this matrix, including the implementation of your interface with which you work, submit them to one unit test method, which represents the general flow of the test and names it.
Here is an example of code that implements the following operations:
// This interface takes two ints, returns one int public interface IBinaryOperation { int Execute(int x, int y); string Name { get; } } public class Add : IBinaryOperation { public int Execute(int x, int y) { return x + y; } public string Name { get { return "Add"; } } } public class Multiply : IBinaryOperation { public int Execute(int x, int y) { return x * y; } public string Name { get { return "Multiply"; } } }
And here is an example implementation of a test adapter:
[Test, TestCaseSource("OperationTestCases")] public void ExecuteReturnsCorrectResult( IBinaryOperation operation, int inputX, int inputY, int expectedResult ) { int actualResult = operation.Execute(inputX, inputY); Assert.That(actualResult, Is.EqualTo(expectedResult), "Expected operation: '{0}', with '{1}' and '{2}' to return '{3}'" , operation.Name , inputX , inputY , expectedResult ); } static object[] OperationTestCases = { new object[] { new Multiply(), 0, 7, 0 }, new object[] { new Multiply(), 3, 6, 18 }, new object[] { new Add(), 0, 0, 0 }, new object[] { new Add(), 5, 6, 11 }, };

More complex examples
If your implementations are more diverse from each other, or you cannot create a simple input / output matrix, it will be more difficult for you.
One option is to submit delegates to the test file. But it is so complicated, unclear and difficult to maintain as it sounds. In that case, you really should write separate unit test methods.