How can I get an instance of the MSTest V2 TestContext in the TestCleanup method? - mstest

I'm migrating an existing codebase to MSTest V2 and running into a problem with the TestContext in the TestCleanup method.
In MSTest V1 the TestContext class was static but in V2 it is an instance. I tried to add a parameter to the TestCleanup method, but then I get this message:
The method must be non-static, public, does not return a value and should not take any parameter.
Ultimately I want to know the name of the test that is being cleaned up and it's test outcome. If it is not possible to get the TestContext, is there any other way to get to that information in the cleanup context?

Since TestCleanup method and TestContext are not static, then you can just use TestContext inside TestCleanup method without any parameters. Here is an example:
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace MyNamespace.Tests
{
[TestClass]
public class MyTestClass
{
public TestContext TestContext { get; set; }
[TestCleanup]
public void MyTestCleanup()
{
TestContext.WriteLine($"Test Cleanup for {TestContext.TestName}");
}
[TestMethod]
public void MyTestMethod1() { }
[TestMethod]
public void MyTestMethod2() { }
}
}

Related

#TestSecurity tests no longer succeeding with custom HttpAuthenticationMechanism

When adding a custom HttpAuthenticationMechanism, the #TestSecurity annotation does no longer work.
setup a project with SmallRye JWT authentication as described in https://quarkus.io/guides/security-jwt
create a #QuarkusTest test with test methods annotated with #TestSecurity(user = "user"), check for status code 200
run the test, they succeed, status code is 200
add a custom HttpAuthenticationMechanism without any custom logic, just forwarding the call (see below, documented in https://quarkus.io/guides/security-customization#dealing-with-more-than-one-http-auth-mechanisms)
tests no longer succeed, because returned result is 401
#Alternative
#Priority(1)
#ApplicationScoped
public class MyHttpAuthenticationMechanism implements HttpAuthenticationMechanism {
#Inject
JWTAuthMechanism jwt;
#Override
public Uni<SecurityIdentity> authenticate(RoutingContext context, IdentityProviderManager identityProviderManager) {
return jwt.authenticate(context, identityProviderManager);
}
#Override
public Uni<ChallengeData> getChallenge(RoutingContext context) {
return jwt.getChallenge(context);
}
#Override
public Set<Class<? extends AuthenticationRequest>> getCredentialTypes() {
return jwt.getCredentialTypes();
}
#Override
public Uni<HttpCredentialTransport> getCredentialTransport(RoutingContext context) {
return jwt.getCredentialTransport(context);
}
}
How can I make the tests suceed again?
Adding the following class under src/test/java seems to be working.
#Alternative
#Priority(1)
#ApplicationScoped
public class TestHttpAuthenticationMechanism extends io.quarkus.test.security.TestHttpAuthenticationMechanism {
}
I assume the io.quarkus.test.security.TestHttpAuthenticationMechanism is not used in tests due the #Alternative and #Priority attributes on MyHttpAuthenticationMechanism. So setting these attributes on a subclass of io.quarkus.test.security.TestHttpAuthenticationMechanism makes this test mechanism being used again.

IInvokedMethodListener expects all config and testmethods to be on implementing class

I am using IInvokedMethodListener of TestNG to carryout certain operations after execution of a test method -
public class MyListener implements IInvokedMethodListener {
#Override
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
Method testMethod = getClass().getMethod(result.getName());
}
#Override
public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
// some magic here
}
But execution of tests using mvn test results in following errors -
java.lang.NoSuchMethodException: com.savingglobal.opsys.webui.util.MyListener.springTestContextPrepareTestInstance
java.lang.NoSuchMethodException: com.savingglobal.opsys.webui.util.MyListener.springTestContextBeforeTestMethod()
and all of the configuration methods and my test methods. Am I using the listener wrong? I am on TestNG 6.9.10
Caution: getClass() will return MyListener.class and result.getName() MAY return the name of the method.
But if you want the executed Method, just use method.getTestMethod().getConstructorOrMethod().getMethod().

register multiple resource instances of same type

I have a resource endpoint that injects a #PathParam into constructor, i.e., different instance per #PathParam value. It all works fine in Jetty. But now I'm trying to write unit tests using Jersey Test Framework, and it seems that the test framework only supports one registered endpoint per type.
So if I do something like this:
#Path("/users")
public class MyResource {
public MyResource(#PathParam("userId") int userId) {
}
#Path("{userId}")
public String get() {
}
}
public class MyTest extends JerseyTestNg.ContainerPerClassTest {
#Override
protected Application configure() {
return new ResourceConfig()
.register(new MyResource(1))
.register(new MyResource(2));
}
#Test
public void test2() {
target("/users/1").request().get();
}
#Test
public void test2() {
target("/users/2").request().get();
}
}
I see that both test1 and test2 are invoking the instance of MyResource(1). Is this expected? Is there a solution to invoke the correct instance?
You should register the resource as a class. Jersey will create it for you. And handle all the injections.
"The example I posted is dumbed down. In reality, my resource constructor has another injected object that I need to mock. So how would I specify a mocked object parameter for the constructor?"
You can do something like
#Mock
private Service service;
#Override
public ResourceConfig configure() {
MockitoAnnotations.initMocks(this);
return new ResourceConfig()
.register(MyResource.class)
.register(new AbstractBinder() {
#Override
protected configure() {
bind(service).to(Service.class);
}
});
}
#Test
public void test() {
when(service.getSomething()).thenReturn("Something");
// test
}
Assuming you are already using the built in HK2 DI, and have an #Inject annotation on the constructor of your resource class, this should work. In the AbstractBinder we are making the mock object injectable. So now Jersey can inject it into your resource.
See Also:
Jersey - How to mock service

CDI SessionScoped POJO inside an in-container JUnit test

I'm testing a web application using JUnit. The buisness layer of this application is writed in EJB stateless classes.
So I do "in container" tests with JUnit and Glassfish-embedded.
All works fine so far, EJBs are injected using lookup functions.
Here are a simple test case :
public class SupportTest {
private static EJBContainer container;
private static MyEJB myEjb;
#BeforeClass
public static void setUpServices() throws NamingException {
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(EJBContainer.MODULES, new File("target/classes"));
container = EJBContainer.createEJBContainer(properties);
myEjb = (MyEJB) container.getContext().lookup("java:global/classes/MyEJB");
}
#Test
public void test() {
myEjb.doSomething("user_login");
}
}
Now I have a SessionScoped POJO (CDI) which keep information such as user login and so on.
This Pojo is injected inside a static class. Like this :
public class MyStaticClass {
public static boolean verifyLogin(String login) {
MySessionPojo mySessionPojo = CDI.current().select(MySessionPojo.class).get();
return mySessionPojo.getLogin().equals(login);
}
}
This static class is used in EJB to secure the buisness code, like this :
#Stateless
public class MyEJB {
public void doSomething(String login) {
if(MyStaticClass.verifyLogin(login)){
//do something
}
}
}
Inside a normal Glassfish 4.1 server, the injection of the POJO inside the static class works fine.
Inside the Glassfish-embedded, the POJO injection fails with this message :
WELD-001303: No active contexts for scope type javax.enterprise.context.SessionScoped
I assume this is because there is no Http Session bound to it.
Is there a way to simulate/create à SessionContext programmatically?
Thanks.
Ok, I finally find a workaround. I use the framework JMockit to replace the static class by a mock class, with fake methods which always return TRUE. (I had already tested Mockito and PowerMock, but both didn't work).

Using #SpringApplicationConfiguration annotation to injecting mocks into a Spring bean

There is the spring-boot application that uses spring-aop. proxy-target-class is true.
I'm trying to create a test for a service class. This service depends on a component class. I want to inject a mock into the service instead of the real component.
I found some similar questions:
Mocking a property of a CGLIB proxied service not working
Injecting Mockito mocks into a Spring bean
I choose this answer to the last question, and I have tried to implement this approach. I chose it because it is not tied to the implementation details of the proxy classes and I can easily use a config class in other tests.
Below there is the example which simulates the real problem.
#org.aspectj.lang.annotation.Aspect
#org.springframework.stereotype.Component
public class Aspect {
#Before("within(demo.Service)")
public void someAdvice() {
System.out.println("advice");
}
}
#org.springframework.stereotype.Service
public class Service {
#Autowired
private Component component;
public void action() {
System.out.println(component.action());
}
}
#org.springframework.stereotype.Component
public class Component {
public String action() {
return "real action";
}
}
#SpringApplicationConfiguration
public class ServiceTest extends BaseTest {
#Autowired
Service service;
#Test
public void testAction() {
service.action();
}
#Configuration
public static class Config {
#Mock Component mock;
public Config() {
MockitoAnnotations.initMocks(this);
}
#Bean
public Component component() {
Mockito.when(mock.action()).thenReturn("mock action");
return mock;
}
}
}
Complete example: https://github.com/eds0404/spring-inject-mock-into-proxy
The above code is not working as I expect, the service does not use mock ("real action" will be printed if you run test). But the above code works fine if the Component class is not marked with #Component annotation, and its objects are created by the method with #Been annotation.
How to solve this issue? If this is wrong approach, what is best practice?

Resources