DryIoc, how to set the properties to the base class? - dryioc

I've written the following POC, but I have to admit I'm very confused on how to achieve this.
public class Parent
{
public string Str;
public Parent()
{
}
}
public class Child : Parent
{
}
public class Program
{
static void Main(string[] args)
{
var container = new Container();
var prop = typeof (Parent).GetMember(nameof(Parent.Str)).First();
var x = new [] { PropertyOrFieldServiceInfo.Of(prop) };
container.Register<Parent, Parent>(made: Made.Of(propertiesAndFields: (r) => x));
// Set "X" somewhere??
container.Register<Child, Child>();
var parent = container.Resolve<Parent>();
var child = container.Resolve<Parent>();
}
}
my goal, is child and (less importantly) parent both have their Str property set to "X".
I need to know because I would like to convert from Spring.Net to DryIoc where it's like the following.
<object id="parentManager_transport" abstract="true">
<property name="EntityManager" ref="entityManager_transport"/>
</object>
<object id="carManager" type="xxx" parent="parentManager_transport"/>
<object id="carMakerManager" type="yyy" parent="parentManager_transport"/>
<object id="carFuelManager" type="zzz" parent="parentManager_transport"/>

There is a sugar PropertiesAndFields static class with methods to specify what to inject based on name, type or condition:
container.Register<Parent>(
made: PropertiesAndFields.Of.Name("Str", serviceKey: "someId"));
To set property just register it. To distinguish it from possibly multiple registered strings specify service key:
container.RegisterInstance("my string", serviceKey: "someId");

Related

Mockito Mock object being ignored and actual function being called

The mock object does not seem to work and the actual function is being called.
My Controller Class is as follows:-
#RestController
public class A {
#PostMapping(path = "/api/methods", consumes = "application/json", produces = "application/json")
public static ResponseEntity<Object> controllerFunction(#Valid #RequestBody String request,
#RequestHeader(value = "header-content") String header_content) {
JSONObject response = B.getAns(request);
return ResponseEntity.status(HttpStatus.OK).body(response.toString());
}
}
My Class B is as follows:-
#Service
public class B {
private static C client;
#Autowired
private C beanClient;
#PostConstruct
public void init() {
B.client = beanClient;
}
public static JSONObject getAns(String request) {
// This is the line that I intend to mock but gets ignored. It goes into the function search instead.
JSONObject resp = client.search(searchRequest, requestHeaderOptions); // assume that these two variables passed as arguments are not null and have some content.
// searchRequest is of type SearchRequest
// requestHeaderOptions is of type RequestOptions
return resp;
}
}
This is my test class :
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = {
ControllerApplication.class, A.class, B.class, C.class
})
#ActiveProfiles("test")
public class ProjectTest {
#Mock
private C client;
#InjectMocks
A a;
private MockMvc mockMvc;
#BeforeSuite
public void setup() {
// I have tried both MockitoAnnotations.initMocks and openMocks. Both don't work
MockitoAnnotations.openMocks(this);
this.mockMvc = MockMvcBuilders.standaloneSetup(a).build();
}
#Test(enabled = true)
public void testing() throws Exception {
JSONObject obj = new JSONObject() // assume this object is not null
// This statement doesn't seem to work
doReturn(obj).when(client).search(any(SearchRequest.Class), any(RequestOptions.Class));
MockHttpServletRequestBuilder mockRequest = MockMvcRequestBuilders.post("/api/methods")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.header("header-content", "something")
.content("someData");
mockMvc.perform(mockRequest)
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().json(jsonResponse));
}
}
If you notice I have created a static variable of the class C in my Class B. This is part of the program structure itself and cannot be changed.
Is it possible to mock the client.search function given this code?
I was able to figure out what the problem was by running the test in debug mode.
I found that the #PostConstruct function in my Class B was getting called before my test function. So class B was creating its own beanClient object different from the mock in my test class. That's why it was going into the function and not mocking it.
I was able to resolve it by changing Class B like so:-
#Service
public class B{
#Autowired
private C client;
public JSONObject getAns(String request){
// This is the line that I intend to mock but gets ignored. It goes into the function search instead.
JSONObject resp =client.search(searchRequest,requestHeaderOptions); // assume that these two variables passed as arguments are not null and have some content.
// searchRequest is of type SearchRequest
// requestHeaderOptions is of type RequestOptions
return resp;
}
I had to change it into a non-static function.
A quick way to resolve your issue is to mock B and stub B.getAns directly.
In order to mock static B, you should add mockito-inline dependency to your pom.xml:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>3.8.0</version>
<scope>test</scope>
</dependency>
You can use Mockito.mockStatic in this way:
try (MockedStatic<B> mockedB = Mockito.mockStatic(B.class)) {
mockedB.when(() -> B.getAns(anyString())).thenReturn(obj);
// ...
}
Therefore, your test code will be:
#Test(enabled = true)
public void testing() throws Exception {
try (MockedStatic<B> mockedB = Mockito.mockStatic(B.class)) {
JSONObject obj = new JSONObject() // assume this object is not null
mockedB.when(() -> B.getAns(anyString())).thenReturn(obj);
MockHttpServletRequestBuilder mockRequest = MockMvcRequestBuilders.post("/api/methods")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.header("header-content", "something")
.content("someData");
mockMvc.perform(mockRequest)
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().json(jsonResponse));
}
}
Note that, when you use MockedStatic, you had better use try-with-resources pattern and do your test in this scope like above.
Read more about mockStatic: https://www.baeldung.com/mockito-mock-static-methods

Is there any way to get Members of a type and all subsequent base types?

I have an `ITypeSymbol' object. If I call GetMembers, it gives me the members of the current type, not the base. I know I can dig it using BaseType property and have some iterative code to fetch all the properties.
Is there any easier way to fetch all members regardless of level at the inheritance hierarchy?
If you're looking for all members whether or not they're accessible:
There is no public API to do this, and internally the Roslyn team's approach is more or less the same as what you've described.
Take a look at the internal extension method GetBaseTypesAndThis(). You could copy this out into your own extension method and use it as follows:
var tree = CSharpSyntaxTree.ParseText(#"
public class A
{
public void AMember()
{
}
}
public class B : A
{
public void BMember()
{
}
}
public class C: B //<- We will be analyzing this type.
{
public void CMember()
{
}
//Do you want this to hide B.BMember or not?
new public void BMember()
{
}
}");
var Mscorlib = MetadataReference.CreateFromAssembly(typeof(object).Assembly);
var compilation = CSharpCompilation.Create("MyCompilation",
syntaxTrees: new[] { tree }, references: new[] { Mscorlib });
var model = compilation.GetSemanticModel(tree);
var classC = tree.GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>().Last();
var typeC = (ITypeSymbol)model.GetDeclaredSymbol(classC);
//Get all members. Note that accessibility isn't considered.
var members = typeC.GetBaseTypesAndThis().SelectMany(n => n.GetMembers());
The following is the definition for GetBaseTypesAndThis()
public static IEnumerable<ITypeSymbol> GetBaseTypesAndThis(this ITypeSymbol type)
{
var current = type;
while (current != null)
{
yield return current;
current = current.BaseType;
}
}
To check for accessibility put a where condition in the following line to check for accessibility:
typeC.GetBaseTypesAndThis().SelectMany(n => n.GetMembers().Where(x => x.DeclaredAccessibility == Accessibility.Public));`

How to combine PropertyData and AutoNSubstituteData attributes in xunit/autofixture?

I am using the [AutoNSubstituteData] attribute, which was posted here:
AutoFixture, xUnit.net, and Auto Mocking
I would like to combine this with the [PropertyData("")] attribute from xunit extensions.
This is my test:
public static IEnumerable<string[]> InvalidInvariant
{
get
{
yield return new string[] { null };
yield return new [] { string.Empty };
yield return new [] { " " };
}
}
[Theory, AutoNSubstituteData, PropertyData("InvalidInvariant")]
public void TestThatGuardsAreTriggeredWhenConnectionStringArgumentIsInvalid(
IDeal deal,
IDbConnection conn,
IDb db,
ISender sender,
string invalidConnString,
string query)
{
deal.Init.Group.Returns(Group.A);
deal.Aggr.Group.Returns(Group.A);
deal.Product.Commodity.Returns(Product.Commodity.E);
var sut = new Handler(db, sender);
Assert.Throws<ArgumentException>(() =>
sut.HandleDeal(deal, conn, invalidConnString, query));
}
Is there a way to combine these attributes or to get the desired functionality (mock everything, except for invalidConnstring, which should be filled with the property-data)?
There are two ways to do this:
Option 1 - Using AutoFixture.Xunit and the CompositeDataAttribute class:
internal class AutoNSubstituteDataAttribute : AutoDataAttribute
{
internal AutoNSubstituteDataAttribute()
: base(new Fixture().Customize(new AutoNSubstituteCustomization()))
{
}
}
internal class AutoNSubstitutePropertyDataAttribute : CompositeDataAttribute
{
internal AutoNSubstitutePropertyDataAttribute(string propertyName)
: base(
new DataAttribute[] {
new PropertyDataAttribute(propertyName),
new AutoNSubstituteDataAttribute() })
{
}
}
Define the test cases as below:
public class Scenario
{
public static IEnumerable<object[]> InvalidInvariantCase1
{
get
{
yield return new string[] { null };
}
}
public static IEnumerable<object[]> InvalidInvariantCase2
{
get
{
yield return new string[] { string.Empty };
}
}
public static IEnumerable<object[]> InvalidInvariantCase3
{
get
{
yield return new string[] { " " };
}
}
}
Then declare the parameterized test as:
public class Scenarios
{
[Theory]
[AutoNSubstitutePropertyData("InvalidInvariantCase1")]
[AutoNSubstitutePropertyData("InvalidInvariantCase2")]
[AutoNSubstitutePropertyData("InvalidInvariantCase3")]
public void AParameterizedTest(
string invalidConnString,
IDeal deal,
IDbConnection conn,
IDb db,
ISender sender,
string query)
{
}
}
Please note that the parameterized parameter invalidConnString have to be declared before the other parameters.
Option 2 - Using Exude:
public class Scenario
{
public void AParameterizedTest(
IDeal deal,
IDbConnection conn,
IDb db,
ISender sender,
string invalidConnString,
string query)
{
}
[FirstClassTests]
public static TestCase<Scenario>[] RunAParameterizedTest()
{
var testCases = new []
{
new
{
invalidConnString = (string)null
},
new
{
invalidConnString = string.Empty
},
new
{
invalidConnString = " "
}
};
var fixture = new Fixture()
.Customize(new AutoNSubstituteCustomization());
return testCases
.Select(tc =>
new TestCase<Scenario>(
s => s.AParameterizedTest(
fixture.Create<IDeal>(),
fixture.Create<IDbConnection>(),
fixture.Create<IDb>(),
fixture.Create<ISender>(),
tc.invalidConnString,
fixture.Create<string>())))
.ToArray();
}
}
The [Theory] attribute works by looking for one or more 'data source attributes'; for example
[InlineData]
[PropertyData]
[ClassData]
etc.
The [AutoData] attribute is just another such attribute, as is your derived [AutoNSubstituteData] attribute.
It's possible to add more than one 'data source attribute' to the same [Theory], as witnessed by the idiomatic use of the [InlineData] attribute:
[Theory]
[InlineData("foo")]
[InlineData("bar")]
[InlineData("baz")]
public void MyTest(string text)
This produces three test cases.
It's also possible to combine [PropertyData] and [AutoData], but it probably doesn't do what you want it to do. This:
[Theory]
[AutoNSubstituteData]
[PropertyData("InvalidInvariant")]
public void MyTest(/* parameters go here */)
will result in 1 + n test cases:
1 test case from [AutoNSubstituteData]
n test cases from the InvalidInvariant property
These two attributes know nothing about each other, so you can't combine them in the sense that they're aware of each other.
However, when you're implementing a property, you can write whatever code you'd like, including using a Fixture instance, so why not just do this?
public static IEnumerable<string[]> InvalidInvariant
{
get
{
var fixture = new Fixture().Customize(new MyConventions());
// use fixture to yield values...,
// using the occasional hard-coded test value
}
}
Another option is to use derive from the InlineAutoDataAttribute, which would enable you to write your test cases like this:
[Theory]
[MyInlineAutoData("foo")]
[MyInlineAutoData("bar")]
[MyInlineAutoData("baz")]
public void MyTest(string text, string someOtherText, int number, Guid id)
This would cause the first argument (text) to be populated with the constants from the attributes, while the remaining parameters are populated by AutoFixture.
Theoretically, you may also be able to combine the [AutoData] and [PropertyData] attributes using the CompositeDataAttribute, but it may not work the way you'd like.
Finally, you could consider using Exude for true first-class parameterized tests.
I have implemented an AutoPropertyDataAttribute that combines xUnit's PropertyDataAttribute with AutoFixture's AutoDataAttribute. I posted it as an answer here.
In your case you will need to inherit from the attribute in the same way as you would from an AutoDataAttribute, with the exception that you pass a fixture creation function instead of an instance:
public class AutoNSubPropertyDataAttribute : AutoPropertyDataAttribute
{
public AutoNSubPropertyDataAttribute(string propertyName)
: base(propertyName, () => new Fixture().Customize(new AutoNSubstituteCustomization()))
{
}
}

Struts2 get object attribute from select tag

My problem is that I don't succeed in getting the attribute of the object of the list of my select tag.
I have a select tag in my .jsp like this :
<s:select list="listFonction" listKey="code" listValue="Libelle"
name="fonctionSelectionne" value="defaultFonction" />
and in my action, i declared an arraylist (with getter and setter) :
private ArrayList<Fonction> listFonction = new ArrayList<Fonction>();
I also have another class Fonction :
public class Fonction {
private int code;
private String libelle;
public Fonction(int code, String libelle)
{
this.code = code;
this.libelle =libelle;
}
public Fonction()
{
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getLibelle() {
return libelle;
}
public void setLibelle(String libelle) {
this.libelle = libelle;
}
}
To get the selected value in my action i declared (whith getter and setter):
Private String fonctionSelectionne;
but i am just abbled to get the code (listkey) of my object with getFonctionSelectionne.
I want to get the code attribute (listkey) and the libelle attribute (listvalue).
Does anyone know how help me ?
thanks
2 points:
it should be libelle, not Libelle
<s:select list="listFonction" listKey="code" listValue="libelle"
name="fonctionSelectionne" value="defaultFonction" />
for list="listFunction", you need getter Collection getListFunction(){} in your action class
UPDATE
i'am not sure to this. but you can give a try.
here is the idea, don't deliver a list, but a map to select tag
Map getListFunction(){
Map<Object, String> map;
Function f = new Function(1, "test");
map.put(f, f.libelle);
return map;
}
then in the jsp:
<s:select list="listFonction" listKey="key" listValue="value"
name="fonctionSelectionne"/>
You should make the setter of the attribute listFonction on the ClassAction

Unit Testing - Use of Structuremap with MOQ

I want generic/oneline statements for structuremap configuration . please see the following code and suggest the changes :
Structuremap configuration class :
class StructureMapTestConfigurationRegistry : Registry
{
/// <summary>
/// Initializes a new instance of the <see cref="DependencyConfigurationRegistry"/> class.
/// </summary>
public StructureMapTestConfigurationRegistry()
{
For<Repository.IRepository<Report>>().Use(MockObjectGenerator<Report>.RepositoryMockSetup());
For<Repository.IRepository<RelatedContent>>().Use(MockObjectGenerator<RelatedContent>.RepositoryMockSetup());
For<Repository.IRepository<Tags>>().Use(MockObjectGenerator<Tags>.RepositoryMockSetup());
For<Repository.IRepository<ArticleTag>>().Use(MockObjectGenerator<ArticleTag>.RepositoryMockSetup());
For<Repository.IRepository<ReferenceBookTag>>().Use(MockObjectGenerator<ReferenceBookTag>.RepositoryMockSetup());
For<Repository.IRepository<EventsTag>>().Use(MockObjectGenerator<EventsTag>.RepositoryMockSetup());
For<Repository.IRepository<CountryFactfileTag>>().Use(MockObjectGenerator<CountryFactfileTag>.RepositoryMockSetup());
}
BootStrapper Class :
public static class TestBootstrapper
{
public static void TestConfigureStructureMap()
{
ObjectFactory.Container.Dispose();
ObjectFactory.Initialize(o => o.AddRegistry(new StructureMapTestConfigurationRegistry()));
ObjectFactory.Container.AssertConfigurationIsValid();
}
}
MockObjectGenerator Class :
public static class MockObjectGenerator<TEntity> where TEntity : class
{
private static List<TEntity> DummyTable
{
get
{
return MockEntities.GetData<TEntity>();
}
}
public static IRepository<TEntity> RepositoryMockSetup()
{
Mock<IRepository<TEntity>> repository = new Mock<IRepository<TEntity>>(MockBehavior.Strict);
repository.Setup(o => o.Fetch(It.IsAny<Expression<Func<TEntity, bool>>>())).Returns((Expression<Func<TEntity, bool>> i) => DummyTable.Where(i.Compile()).ToList());
repository.Setup(o => o.Create(It.IsAny<IEnumerable<TEntity>>())).Callback<IEnumerable<TEntity>>(items => DummyTable.AddRange(items));
repository.Setup(o => o.Delete(It.IsAny<TEntity>())).Callback<TEntity>(item => DummyTable.Remove(item));
}
}
**Mock Entities Class :**
public static class MockEntities
{
public static Dictionary<string, dynamic> MockData = new Dictionary<string, dynamic>();
public static void LoadData()
{
MockData.Add(typeof(CMSModel.Article).Name, ArticleTestData.GetTestRecords());
MockData.Add(typeof(CMSModel.ArticleTag).Name, RelatedArticleContentTestData.GetTestRecords());
}
public static List<T> GetData<T>() where T : class
{
return (List<T>)MockData[typeof(T).Name];
}
}
Note :
This has been done so that in actual unit test , We dont have to write setup methods since that is done while creating dependent object using structuremap.
It works fine, but I want to refactor the configuration file code to generic
I have writen it for implentation like this :
For(typeof(Repository.IRepository<>)).Use(typeof(Repository.Repository<>));
is it possible for unit test configuration ?
It is possible, though you'd need to specify all types entity types that are going to be used and pass them as Types. And you'll need to use non-generic version of functions (to be able to write For(type) instead of For). That way all your functions would work only on type variables and would look like simple methods.