How can I remove duplication from TestCaseSource attribute in NUnit? - nunit

I have multiple test classes that have the same TestCaseSource parameters being passed in. The reason that I have multiple test classes is for parallelization of tests, which can only be done at the class level in NUnit. So, When I create a new class, I have to keep copying the line of code. I wonder if there is some way to remove this duplication.
[TestCaseSource(typeof(VisualValidationDataGetter), nameof(TestDataGetter.VisualValidation.GetDataByBlockCode),
new object[] { ItemType })]
public void VisualValidationTestMethod(VisualValidationCsvRecord testData)
{
PerformStepsForVisualValidation(studentData);
}
I have about 10 such test classes with a call to this test method and these TestCaseSource properties. The only thing that changes is ItemType, which is defined at the class level. Every test class has a different ItemType, which resukts in different test data. Is it possible to just call a test method and not have to keep repeating the call to this TestCaseSource line:
[TestCaseSource(typeof(VisualValidationDataGetter), nameof(TestDataGetter.VisualValidation.GetDataByBlockCode),
new object[] { ItemType })]
Thanks in advance.

Related

Prevent NUnit from executing test setup method from another class?

I've got an odd question for which Google has proven barren:
I've got a project in .net with ~20 classes that all have tests in them. One of the classes has common test setup code, although a few of the classes have their own TestFixtureSetup that looks exactly like the common class (not my architecture choice - this predates my employment). I have my own test class for which I have some different code that runs prior to running a few particular tests within the class.
Some more info that's relevant: The custom setup code that I have enables data to be available for a few combinatorial tests I have in my own test class. As the value source for the combinatorial params, the List that is returned first initializes some data.
Alright, here's the question: When I try to run a test in ANOTHER test class, it's "building" the tests from every other class. In my case, it's building the combinatorial test that I have - and thus, triggering the custom setup method that I have.
How do I prevent NUnit from building tests in other classes? As in, I run a test in one class, all I'd like NUnit to do is build tests from that class ONLY.
I tried to remove any NDA-no-no language, but here's the combinatorial I have:
[Test, Combinatorial, Category("Regressive")]
public void Test05_CombiTestExample(
[ValueSource("ListA")] User user,
[ValueSource("ListB")] KeyValuePair<string, string> searchKvp,
[ValueSource("ListC")] string scope)
{
And here's one of the lists that is being reference:
public IEnumerable<KeyValuePair<string, string>> ListB
{
get
{
InitCustomData();
if ([Redacted] != null)
{
return new Dictionary<string, string>()
{
[Redacted]
};
}
return null;
}
}
The line in question is "InitCustomData();" which, because my combinatorial is being built prior to running any setup or anything, is being executed anyway. I want this to stay here - I just don't want NUnit to start building test cases from any other class besides the one it's currently running a test in.

How to test default case when using Junit Parameterized.class

I have an old version API: Foo(). Now I extend the API to Foo(false), Foo(true) and Foo() should still work as before.
Right now I am using Parameterized.class to do Junit, and the parameter list is {null, false, true}. I want to write the testcase as:
#Test
public void fooTest() {
Foo(parameter);
}
But Foo(parameter) cannot test Foo(), so I have to write the test code as:
#Test
public void fooTest() {
if (parameter == null)
Foo();
else
Foo(parameter);
}
Is there any simple way to write the test case so that I do not need to check whether parameter is null or not? I ask this because the original test cases before I extend API are already there in many places (see below) and I do not want to change the test code too much. :
#Test
public void fooTest() {
Foo();
}
One way could be to put the Foo-Object (instead of the constructor arguments) into the parameters, i.e. {Foo(false), Foo(true),Foo()} instead of {null, false, true}
Yet review your example. Probably it is an abstraction of a real problem. If not:
assertions are missing, these should be contained in the parameters (otherwise you get the if-problem in the assertion phase).
testing with 3 parameter values is easier done with 3 simple (un-parameterized) unittests
And you could of course put your default constructor into a separate (un-parametereized) test class.
Which alternative is the best depends heavily on the real problem behind your abstraction.

Why does Entity make a duplicate of related item when trying to add readonly object?

I've been trying to write some tests for my program and got a strange problem.
The db looks like one-TableOne to many TableMany (let's say so)
Initialization before every test is pretty simple. Remove everything existing and insert new ones before every test. Everything works.
[TestInitialize()]
public void MyTestInitialize() // Before every test run.
{
FixtureDbTearDown.TearDown( FixtureDbImport_95.ID );
FixtureDbImport_95.SetUp();
}
Then I have decided to use re-use fixture and clean it up. So I made all entity classes private static readonly.
Now, only first test passes, others throw an exception on duplicate key. Running tests one by one shows no errors.
Basically, this is working
private static void SetUp_Many( MyEntities entity )
{
TableMany ok1 = new TableMany { smth... };
entity.TableMany.Add( ok1 );
}
But this one not.
private static readonly TableMany ok_sr = new TableMany { smth.. };
private static void SetUp_Many( MyEntities entity )
{
entity.TableMany.Add( ok_sr );
}
Debugger shows that the second I call Add(ok_sr) entitty adds one more record to parent TableOne.
The TableOne is an exact copy of mine, no nulls and default values.
Ok, I can make a object copy before adding, most likely, the problem is with object copy because I declare things readonly. Right?
I am a little bit confused about the duplicate for TableOne.
Any ideas?
The member variable ok_sr is readonly but the object ok_sr itself isn't!
When a member is readonly you can't assign another object to it after the first assignment. But if the object itself has read/write properties or state-changing methods you can still modify the object.
This is exactly what happens here. After the first test, ok_sr has obtained a parent, a "TableOne" instance. Now when you execute ...
entity.TableMany.Add(ok_sr);
... the parent object is marked as Added as well. As for EF, it's a brand new entity, even though its primary key has a value. EF just overwrites this key value.
As a general advice, I would not use static members for unit test unless it's for genuinely read-only values, i.e. value types.
A very elegant way of cleaning up in unit tests against a database (these are, in fact, integration tests) is to start a transaction scope in the setup of each test and dispose it without committing it in each test teardown.

How to call constructor with interface arguments when mocking a concrete class with Moq

I have the following class, which uses constructor injection:
public class Service : IService
{
public Service(IRepository repository, IProvider provider) { ... }
}
For most methods in this class, I simply create Moq mocks for IRepository and IProvider and construct the Service. However, there is one method in the class that calls several other methods in the same class. For testing this method, instead of testing all those methods together, I want to test that the method calls those methods correctly and processes their return values correctly.
The best way to do this is to mock Service. I've mocked concrete classes with Moq before without issue. I've even mocked concrete classes that require constructor arguments with Moq without issue. However, this is the first time I've needed to pass mocked arguments into the constructor for a mocked object. Naturally, I tried to do it this way:
var repository = new Mock<IRepository>();
var provider = new Mock<IProvider>();
var service = new Mock<Service>(repository.Object, provider.Object);
However, that does not work. Instead, I get the following error:
Castle.DynamicProxy.InvalidProxyConstructorArgumentsException : Can not instantiate proxy of class: My.Namespace.Service.
Could not find a constructor that would match given arguments:
Castle.Proxies.IRepository
Castle.Proxies.IProvider
This works fine if Service's constructor takes simple arguments like ints and strings, but not if it takes interfaces that I'm mocking. How do you do this?
Why are you mocking the service you are testing? If you are wishing to test the implementation of the Service class (whether that be calls to mocked objects or not), all you need are mocks for the two interfaces, not the test class.
Instead of:
var repository = new Mock<IRepository>();
var provider = new Mock<IProvider>();
var service = new Mock<Service>(repository.Object, provider.Object);
Shouldn't it be this instead?
var repository = new Mock<IRepository>();
var provider = new Mock<IProvider>();
var service = new Service(repository.Object, provider.Object);
I realize that it is possible to mock concrete objects in some frameworks, but what is your intended purpose? The idea behind mocking something is to remove the actual implementation so that it does not influence your test. But in your question, you have stated that you wish to know that certain classes are called on properly, and then you wish to validate the results of those actions. That is undoubtedly testing the implementation, and for that reason, I am having a hard time seeing the goals of mocking the concrete object.
I had a very similar problem when my equivalent of Service had an internal constructor, so it was not visible to Moq.
I added
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
to my AssemblyInfo.cs file for the implementing project. Not sure if it is relevant, but I wanted to add a suggestion on the off chance that it helps you or someone else.
It must be old version issue, all is ok with latest version. Nick, Please check!
P.s.: I started bounty by misstake (I had wrong signature in my constructor).

DbContext Object in EntityFramework

In Business Logic Layer i do have a process that has 8 steps . And in DAL am using EntiyFrameWork Code first approach. I have created an object of Container that inherits DBContext like(using(var context=new MyContainer)) in every method where i have to do DBoperaions. For performance part i saw it took time when i create its object. Can i make Object of that container once in Bll (at the beginning of process) and pass it to all the methods as parameter and dispose that object at the end of the process after completing all the 8 steps. Any help will be highly appericiated.
Yes, you should create exactly one ObjectContext per unit of work.
You can either pass the OC to the steps, or just the parts needed. E.g., if you only need to query MyEntities.Foos for some step, you can do:
public class Step4
{
public Step4(IQueryable<Foo> foos)
{
// ...
...and then do:
var step4Result = new Step4(context.Foos).Execute();
This will be easier to test than passing the whole context.