### Question:
QueryUtil { public static String constructUpsertStatement(String tableName, List<ColumnInfo> columnInfos) { if (columnInfos.isEmpty()) { throw new IllegalArgumentException("At least one column must be provided for upserts"); } final List<String> columnNames = Lists.transform(columnInfos, new Function<ColumnInfo,String>() { @Override public String apply(ColumnInfo columnInfo) { return columnInfo.getColumnName(); } }); return constructUpsertStatement(tableName, columnNames, null); } private  QueryUtil(); static String toSQL(CompareOp op); static String constructUpsertStatement(String tableName, List<ColumnInfo> columnInfos); static String constructUpsertStatement(String tableName, List<String> columns, Hint hint); static String constructGenericUpsertStatement(String tableName, int numColumns); static String constructSelectStatement(String fullTableName, List<ColumnInfo> columnInfos,final String conditions); static String constructSelectStatement(String fullTableName, List<String> columns,
            final String conditions, Hint hint, boolean escapeCols); static String constructParameterizedInClause(int numWhereCols, int numBatches); static String getUrl(String zkQuorum); static String getUrl(String zkQuorum, int clientPort); static String getUrl(String zkQuorum, String znodeParent); static String getUrl(String zkQuorum, int port, String znodeParent, String principal); static String getUrl(String zkQuorum, int port, String znodeParent); static String getUrl(String zkQuorum, Integer port, String znodeParent); static String getUrl(String zkQuorum, Integer port, String znodeParent, String principal); static String getExplainPlan(ResultSet rs); static String getExplainPlan(ResultIterator iterator); static Connection getConnectionOnServer(Configuration conf); static void setServerConnection(Properties props); static boolean isServerConnection(ReadOnlyProps props); static Connection getConnectionOnServer(Properties props, Configuration conf); static Connection getConnectionOnServerWithCustomUrl(Properties props, String principal); static Connection getConnection(Configuration conf); static String getConnectionUrl(Properties props, Configuration conf); static String getConnectionUrl(Properties props, Configuration conf, String principal); static String getViewStatement(String schemaName, String tableName, String where); static Integer getOffsetLimit(Integer limit, Integer offset); static Integer getRemainingOffset(Tuple offsetTuple); static String getViewPartitionClause(String partitionColumnName, long autoPartitionNum); static Connection getConnectionForQueryLog(Configuration config); static final int COLUMN_FAMILY_POSITION; static final int COLUMN_NAME_POSITION; static final int DATA_TYPE_POSITION; static final int DATA_TYPE_NAME_POSITION; static final String IS_SERVER_CONNECTION; }### Answer:
@Test public void testConstructUpsertStatement_ColumnInfos() { assertEquals( "UPSERT INTO MYTAB (\"ID\", \"NAME\") VALUES (?, ?)", QueryUtil.constructUpsertStatement("MYTAB", ImmutableList.of(ID_COLUMN, NAME_COLUMN))); }
@Test(expected=IllegalArgumentException.class) public void testConstructUpsertStatement_ColumnInfos_NoColumns() { QueryUtil.constructUpsertStatement("MYTAB", ImmutableList.<ColumnInfo>of()); }