模拟 JNDI DNS 接口
mocking JNDI DNS interface
我有一个项目,我们使用 JNDI 来查询 DNS 记录。该项目本身运行良好,但是我找不到使用 jUnit 测试 JNDI 依赖组件的简单且独立的方法。
代码远非火箭科学,看起来很像典型的普通 JNDI DNS 请求。
目前我将测试单元指向 public DNS 记录(A、MX、TXT 记录),但这有点不行。
...
Hashtable env = new Hashtable();
env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
env.put("com.sun.jndi.dns.timeout.initial", timeOut);
env.put("com.sun.jndi.dns.timeout.retries", retries);
env.put("java.naming.provider.url", dns:);
}
Attributes attrs;
try {
DirContext ictx = new InitialDirContext(env);
attrs = ictx.getAttributes(queryInput, new String[]{queryType});
return attrs;
} catch ( NameNotFoundException e) {
getLogger().debug("Resolution for domain {} failed due to {}", new Object[]{queryInput, e});
attrs = new BasicAttributes(queryType, "NXDOMAIN",true);
return attrs;
有没有办法将 TXT 和 A 响应注入 JNDI?
事实证明,可以使用传统的 JNDI 模拟策略(如使用 Mockito.when
),但将条件钉在 getAttributes 方法中,如下面的示例代码所示:
@Before
public void setupTest() throws Exception {
this.queryDNS = new QueryDNS();
this.queryDNSTestRunner = TestRunners.newTestRunner(queryDNS);
Hashtable env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, FakeDNSInitialDirContextFactory.class.getName());
this.queryDNS.initializeContext(env);
final DirContext mockContext = FakeDNSInitialDirContextFactory.getLatestMockContext();
// Capture JNDI's getAttibutes method containing the (String) queryValue and (String[]) queryType
Mockito.when( mockContext.getAttributes(Mockito.anyString(), Mockito.any(String[].class)))
.thenAnswer(new Answer() {
public Object answer(InvocationOnMock invocation) throws Throwable {
// Craft a false DNS response
// Note the DNS response will not make use of any of the mocked
// query contents (all input is discarded and replies synthetically
// generated
return craftResponse(invocation);
}
});
}
和
// Dummy pseudo-DNS responder
private Attributes craftResponse(InvocationOnMock invocation) {
Object[] arguments = invocation.getArguments();
String querySubject = arguments[0].toString();
String[] queryType = (String[]) arguments[1];
// Create attribute
Attributes attrs = new BasicAttributes(true);
BasicAttribute attr;
switch (queryType[0]) {
case "AAAA":
attr = new BasicAttribute("AAAA");
attrs.put(attr);
break;
case "TXT":
attr = new BasicAttribute("TXT", "666 | 123.123.123.123/32 | Apache-NIFI | AU | nifi.org | Apache NiFi");
attrs.put(attr);
break;
case "PTR":
attr = new BasicAttribute("PTR");
attr.add(0, "eg-apache.nifi.org.");
attr.add(1, "apache.nifi.org.");
attrs.put(attr);
break;
}
return attrs;
}
希望这对以后的人有所帮助。
我有一个项目,我们使用 JNDI 来查询 DNS 记录。该项目本身运行良好,但是我找不到使用 jUnit 测试 JNDI 依赖组件的简单且独立的方法。
代码远非火箭科学,看起来很像典型的普通 JNDI DNS 请求。
目前我将测试单元指向 public DNS 记录(A、MX、TXT 记录),但这有点不行。
...
Hashtable env = new Hashtable();
env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
env.put("com.sun.jndi.dns.timeout.initial", timeOut);
env.put("com.sun.jndi.dns.timeout.retries", retries);
env.put("java.naming.provider.url", dns:);
}
Attributes attrs;
try {
DirContext ictx = new InitialDirContext(env);
attrs = ictx.getAttributes(queryInput, new String[]{queryType});
return attrs;
} catch ( NameNotFoundException e) {
getLogger().debug("Resolution for domain {} failed due to {}", new Object[]{queryInput, e});
attrs = new BasicAttributes(queryType, "NXDOMAIN",true);
return attrs;
有没有办法将 TXT 和 A 响应注入 JNDI?
事实证明,可以使用传统的 JNDI 模拟策略(如使用 Mockito.when
),但将条件钉在 getAttributes 方法中,如下面的示例代码所示:
@Before
public void setupTest() throws Exception {
this.queryDNS = new QueryDNS();
this.queryDNSTestRunner = TestRunners.newTestRunner(queryDNS);
Hashtable env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, FakeDNSInitialDirContextFactory.class.getName());
this.queryDNS.initializeContext(env);
final DirContext mockContext = FakeDNSInitialDirContextFactory.getLatestMockContext();
// Capture JNDI's getAttibutes method containing the (String) queryValue and (String[]) queryType
Mockito.when( mockContext.getAttributes(Mockito.anyString(), Mockito.any(String[].class)))
.thenAnswer(new Answer() {
public Object answer(InvocationOnMock invocation) throws Throwable {
// Craft a false DNS response
// Note the DNS response will not make use of any of the mocked
// query contents (all input is discarded and replies synthetically
// generated
return craftResponse(invocation);
}
});
}
和
// Dummy pseudo-DNS responder
private Attributes craftResponse(InvocationOnMock invocation) {
Object[] arguments = invocation.getArguments();
String querySubject = arguments[0].toString();
String[] queryType = (String[]) arguments[1];
// Create attribute
Attributes attrs = new BasicAttributes(true);
BasicAttribute attr;
switch (queryType[0]) {
case "AAAA":
attr = new BasicAttribute("AAAA");
attrs.put(attr);
break;
case "TXT":
attr = new BasicAttribute("TXT", "666 | 123.123.123.123/32 | Apache-NIFI | AU | nifi.org | Apache NiFi");
attrs.put(attr);
break;
case "PTR":
attr = new BasicAttribute("PTR");
attr.add(0, "eg-apache.nifi.org.");
attr.add(1, "apache.nifi.org.");
attrs.put(attr);
break;
}
return attrs;
}
希望这对以后的人有所帮助。