I have a class in which there is a parameter less constructor. But when this constructor is called, there are five properties of the class that gets values from config file in the constructor. There are two method in the class which uses the parameters that get initialized in the constructor.
I want to write unit test for two methods using mock framework. But, I am not sure of how to initialize the parameters in the constructor as calling the method will not provide the value to those properties.
public class ABC
{
public ABC()
{
a = ConfigurationManager.AppSetting["GetValue"];
b = ConfigurationManager.AppSetting["GetValue1"];
}
public int Method1(IDictionary<string, string> dict)
{
d = a + b /2; (how to mock values of a and b while writing unit tests
using mock framework. In reality, a in my case is
dictionary)
//some business logic
return d;
}
}
Thanking in advance,
You cannot Mock values of a and b as your code is tightly coupled with app.config file. You can create an interface. Refactor code like below to inject an interface to you constructor and then mock it,
public class ABC
{
private int a;
private int b;
public ABC(IConfig config)
{
a = config.a;
b = config.b;
}
public int Method1(IDictionary<string, string> dict)
{
int d = a + b / 2;
return d;
}
}
public interface IConfig
{
int a { get; }
int b { get; }
}
public class Config : IConfig
{
public int a => Convert.ToInt32(ConfigurationManager.AppSettings["GetValue"]);
public int b => Convert.ToInt32(ConfigurationManager.AppSettings["GetValue1"]);
}
And in you test class Mock and inject IConfig like below,
Mock<IConfig> _mockConfig = new Mock<IConfig>();
_mockConfig.Setup(m => m.a).Returns(1);
_mockConfig.Setup(m => m.b).Returns(2);
ABC abc = new ABC(_mockConfig.Object);
Now your code is decoupled with app.config and you will get mock values of a and b while running unit test.
Related
ClassToMock.hpp
enum class Flavors {Vanilla, Strawberry};
class ClassToMock
{
public:
Flavors flavorName = Flavors::Vanilla;
.....
}
ClassRunner.cpp
class Runner
{
void main()
{
....
ClassToMock* classToMock = new ClassToMock();
if (classToMock->flavorName == Flavors::Strawberry)
{
...
}
...
}
}
I want to write a unit test that sets the value of class variable flavorName to Flavors::Strawberry and test the if() branch.
If I were to mock functions its easy to mock (mark the function in ClassToMock.hpp as virtual and mock it). But since flavorName is not a function, I am not able to set the value of flavorName to Strawberry in the test code. The value of flavorName is always set to the default value i.e. Vanilla when I call the main() from the TestCode.cpp.
TestCode.cpp
TEST_F(...)
{
Runner* runner = new Runner();
EXPECT_NO_THROW(runner->main());
}
I have also tried to create a mock class,
class MockClassToMock : public ClassToMock
{
public:
Flavors flavorName = Flavors::Vanilla;
}
but still changes are not picked.
I'm using Weld for CDI.
I'm trying to write a unit test for service "A" using JUnit 5.
The constructor of service A is:
#Inject
public A (B b) {this.b = b}
Class B constructor is:
#ApplicationScoped
public class B{
private C c;
public B() {
c = CDI.current().select(C.class).get();
}
}
When i try to mock Class B during unit tests i get:
java.lang.IllegalStateException: Unable to access CDI
because during unit tests there isn't a proper CDI container.
How can resolve this issue? is there anyway to it with Mockito? (let's assume that replacing the CDI.current() is not an option)
This how the test code looks:
public class ATest {
private A a;
#WeldSetup
private WeldInitiator weld = WeldInitiator.from(A.class)
.addBeans(createBBean()).build();
private Bean<?> createBBean() {
return MockBean.builder()
.types(B.class)
.scope(ApplicationScoped.class)
.creating(new B())
.build();
}
#BeforeEach
void setUpClass() {
a = weld.select(A.class).get();
}
}
I always do this (CDI 2.0 and later):
private SeContainer container;
#BeforeEach
private void startContainer() {
SeContainerInitializer initializer = SeContainerInitializer.newInstance();
// add what you want, disable discovery, whatever
this.container = initializer.initialize();
}
#AfterEach
private void stopContainer() {
if (this.container != null) {
this.container.close();
}
}
Then any #Test has access to CDI.
In TestNG I have a parameterized Test A which automatically creates n tests from a dataProvider, and a Test B which should be executed each time a test in A finishes as I want to take advantage of the result obtained in A. In other words, I would like to know is it's possible to have the following:
Given a parameterized #Test A(dataProvider = "inputList") and a #Test B, TestNG would create the following unit tests and execute them in the following order:
Test A1
Test B1 (Based on A1 result)
Test A2
Test B2 (Based on B2 result)
...
Test An
Test Bn (Based on An result)
Is it possible with any existing TestNG tag? I know I could treat #Test B as an #After but this wouldn't be understood for TestNG as a test and I need Test B to be seen as a test for later reports.
You can use a TestNG Factory. e.g.:
On a Factory Method
public class TestClass {
private final int p1;
private final int p2;
public TestClass(int p1, int p2) {
this.p1 = p1;
this.p2 = p2;
}
#Factory(dataProvider = "inputList")
public static Object[] createTestClasses() {
return new Object[]{
new TestClass(1, 1),
new TestClass(1, 0),
new TestClass(1, -1),
};
}
#Test
public void A() {
// test `A` code, stores result in some class member field
}
#Test(dependsOnMethods = {"A"})
public void B() {
// test `B` code, uses stored result from test `A`
}
}
On a Constructor
public class TestClass {
private final int p1;
private final int p2;
#Factory(dataProvider = "inputList")
public TestClass(int p1, int p2) {
this.p1 = p1;
this.p2 = p2;
}
#DataProvider
public static Object[][] inputList() {
return new Object[][]{
{1, 1},
{1, 0},
{1, -1}
};
}
#Test
public void A() {
// test `A` code, stores result in some class member field
}
#Test(dependsOnMethods = {"A"})
public void B() {
// test `B` code, uses stored result from test `A`
}
}
See Factories in the TestNG documentation page.
Already good answer is provided, if you are just looking forward to execute #Test methods in required order then you can use priority. If you want to specify the dependency between methods, then you can use dependsOnMethods. below is the simple example
#Test(priority=1)
public void testA1(){
}
#Test(priority=2,dependsOnMethods="testA1")
public void testB1(){
}
#Test(priority=3)
public void testA2(){
}
#Test(priority=4,dependsOnMethods="testA2")
public void testB2(){
}
In the following test case where no Expectations have been recorded, I would expect that the dynamic partial mocking feature will be used for the fields A and B which are initialized in UnitToTest using #Injectable. But instead always the method calls are mocked. Only using an invalid filter value for static partial mocking, it is possible to call the real methods:
#Service
class A {
public String doSomething() { return "doSomething"; }
public String doSomethingElse() { return "doSomethingElse"; }
}
#Service
class B {
public String doSomething() { return "doSomething"; }
public String doSomethingElse() { return "doSomethingElse"; }
}
#Service
class UnitToTest {
#Autowired B b;
#Autowired A a;
public B getB() { return b; }
public A getA() { return a; }
}
public class TestClass {
#Tested UnitToTest unit;
// #Mocked({ "someInvalidFilter()" })
#Injectable A a;
// #Mocked({ "someInvalidFilter()" })
#Injectable B b;
#Test
public void test() {
// actual return value is always null if no invalid static partial
// mocking filters are specified above
assertEquals("doSomething", unit.getA().doSomething());
assertEquals("doSomethingElse", unit.getA().doSomethingElse());
assertEquals("doSomething", unit.getB().doSomething());
assertEquals("doSomethingElse", unit.getB().doSomethingElse());
}
}
For me it looks like dynamic partial mocking with JMockit doesn't work for #Injectables. Is that a known restriction?
#Injectables always get injected into #Tested objects, assuming a matching field or constructor parameter can be found; the injection process even takes into consideration DI annotations such as #Inject and #Autowired.
However, an #Injectable instance is always created as an uninitialized (ie, with no state) and fully mocked instance. Partial mocking, on the other hand, is meant for real instances that you instantiate (and initialize) yourself in the test.
So, what you seem to be asking for is that said real instances (partially mocked or not) could be injected into #Tested objects. Indeed, this is not supported (except by calling Deencapsulation.setField), since a motivating use case was never presented by users.
That said, the example test will pass if it is changed to the following:
public class TestClass {
#Tested(fullyInitialized = true) UnitToTest unit;
#Test
public void test() {
assertEquals("doSomething", unit.getA().doSomething());
assertEquals("doSomethingElse", unit.getA().doSomethingElse());
assertEquals("doSomething", unit.getB().doSomething());
assertEquals("doSomethingElse", unit.getB().doSomethingElse());
}
}
The above is an integration test, though, not a unit test.
I am unit testing legacy code and I am dealing with a class that instantiates another class. I believe this is testable using Microsoft Fakes, but am wondering if NSubstitute has the capability. I believe the answer is no, but need to be sure.
public class ClassA
{
public int MethodA()
{
int reportId = this.MethodB();
return reportId;
}
public virtual int MethodB()
{
ClassC c = new ClassC();
return c.MethodA();
}
}
public class ClassC
{
public virtual int MethodA()
{
return 2;
}
}
[Test]
public void Test_ClassA()
{
ClassA subclassA = new ClassA();
var subclassC = Substitute.For<ClassC>(); //this is pointless the way I have it here
subclassC.MethodA().Returns(1); //this is pointless the way I have it here
int outValue = subclassA.MethodA();
Assert.AreEqual(outValue, 1); //outvalue is 2 but I would like it to be 1 if possible using Nsubstitute
}
It is possible to override virtual methods in classes by using partial substitution: just make sure that the base code cannot be called by specifying that the base class must not be called:
var A = Substitute.ForPartsOf<ClassA>();
var C = Substitute.ForPartsOf<ClassC>();
C.When(c => c.MethodA()).DoNotCallBase();
C.MethodA().Returns(10);
A.When(a => a.MethodB()).DoNotCallBase();
var cResult = C.MethodA();
A.MethodB().Returns(cResult);
Console.WriteLine(A.MethodB());
Console.WriteLine(C.MethodA());